2025-12-07 17:15:09 +02:00
# api.py
from fastapi import (
FastAPI ,
Query ,
Request , UploadFile ,
File ,
Form
)
2025-12-13 00:23:03 +02:00
from fastapi . responses import StreamingResponse
from typing import List , Optional
2025-12-07 17:15:09 +02:00
from pydantic import BaseModel
import globals
from server_manager import server_manager
from utils . conversation_history import conversation_history
from commands . actions import (
force_sleep ,
wake_up ,
set_mood ,
reset_mood ,
check_mood ,
calm_miku ,
reset_conversation ,
send_bedtime_now
)
from utils . autonomous import (
miku_autonomous_tick ,
miku_say_something_general ,
miku_engage_random_user ,
share_miku_tweet ,
2025-12-10 14:57:59 +02:00
handle_custom_prompt ,
miku_detect_and_join_conversation
2025-12-07 17:15:09 +02:00
)
import asyncio
import nest_asyncio
import subprocess
import io
import discord
import aiofiles
2025-12-13 00:23:03 +02:00
import aiohttp
2025-12-07 17:15:09 +02:00
from fastapi . staticfiles import StaticFiles
from fastapi . responses import FileResponse , PlainTextResponse
import os
import json
from utils . figurine_notifier import (
load_subscribers as figurine_load_subscribers ,
add_subscriber as figurine_add_subscriber ,
remove_subscriber as figurine_remove_subscriber ,
send_figurine_dm_to_all_subscribers ,
send_figurine_dm_to_single_user
)
from utils . dm_logger import dm_logger
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 , list_components , get_component_stats
from utils . log_config import (
load_config as load_log_config ,
save_config as save_log_config ,
update_component ,
update_global_level ,
update_timestamp_format ,
update_api_filters ,
reset_to_defaults ,
reload_all_loggers
)
import time
from fnmatch import fnmatch
2025-12-07 17:15:09 +02:00
nest_asyncio . apply ( )
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 API logger
logger = get_logger ( ' api ' )
api_requests_logger = get_logger ( ' api.requests ' )
2026-01-09 00:03:59 +02:00
# ========== GPU Selection Helper ==========
def get_current_gpu_url ( ) :
""" Get the URL for the currently selected GPU """
gpu_state_file = os . path . join ( os . path . dirname ( __file__ ) , " memory " , " gpu_state.json " )
try :
with open ( gpu_state_file , " r " ) as f :
state = json . load ( f )
current_gpu = state . get ( " current_gpu " , " nvidia " )
if current_gpu == " amd " :
return globals . LLAMA_AMD_URL
else :
return globals . LLAMA_URL
except :
# Default to NVIDIA if state file doesn't exist
return globals . LLAMA_URL
2025-12-07 17:15:09 +02:00
app = FastAPI ( )
2026-01-20 23:06:17 +02:00
# ========== Global Exception Handler ==========
@app.exception_handler ( Exception )
async def global_exception_handler ( request : Request , exc : Exception ) :
""" Catch all unhandled exceptions and log them properly. """
logger . error ( f " Unhandled exception on { request . method } { request . url . path } : { exc } " , exc_info = True )
return { " success " : False , " error " : " Internal server error " }
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
# ========== Logging Middleware ==========
@app.middleware ( " http " )
async def log_requests ( request : Request , call_next ) :
""" Middleware to log HTTP requests based on configuration. """
start_time = time . time ( )
# Get logging config
log_config = load_log_config ( )
api_config = log_config . get ( ' components ' , { } ) . get ( ' api.requests ' , { } )
# Check if API request logging is enabled
if not api_config . get ( ' enabled ' , False ) :
return await call_next ( request )
# Get filters
filters = api_config . get ( ' filters ' , { } )
exclude_paths = filters . get ( ' exclude_paths ' , [ ] )
exclude_status = filters . get ( ' exclude_status ' , [ ] )
include_slow_requests = filters . get ( ' include_slow_requests ' , True )
slow_threshold_ms = filters . get ( ' slow_threshold_ms ' , 1000 )
# Process request
response = await call_next ( request )
# Calculate duration
duration_ms = ( time . time ( ) - start_time ) * 1000
# Check if path should be excluded
path = request . url . path
for pattern in exclude_paths :
if fnmatch ( path , pattern ) :
return response
# Check if status should be excluded (unless it's a slow request)
is_slow = duration_ms > = slow_threshold_ms
if response . status_code in exclude_status and not ( include_slow_requests and is_slow ) :
return response
# Log the request
log_msg = f " { request . method } { path } - { response . status_code } ( { duration_ms : .2f } ms) "
if is_slow :
api_requests_logger . warning ( f " SLOW REQUEST: { log_msg } " )
elif response . status_code > = 500 :
api_requests_logger . error ( log_msg )
elif response . status_code > = 400 :
api_requests_logger . warning ( log_msg )
else :
api_requests_logger . api ( log_msg )
return response
2025-12-07 17:15:09 +02:00
# Serve static folder
app . mount ( " /static " , StaticFiles ( directory = " static " ) , name = " static " )
# ========== Models ==========
class MoodSetRequest ( BaseModel ) :
mood : str
class ConversationResetRequest ( BaseModel ) :
user_id : str
class CustomPromptRequest ( BaseModel ) :
prompt : str
class ServerConfigRequest ( BaseModel ) :
guild_id : int
guild_name : str
autonomous_channel_id : int
autonomous_channel_name : str
bedtime_channel_ids : List [ int ] = None
enabled_features : List [ str ] = None
2026-01-02 17:11:58 +02:00
class EvilMoodSetRequest ( BaseModel ) :
mood : str
2025-12-07 17:15:09 +02:00
# ========== Routes ==========
@app.get ( " / " )
def read_index ( ) :
return FileResponse ( " static/index.html " )
@app.get ( " /logs " )
def get_logs ( ) :
try :
# Read last 100 lines of the log file
with open ( " /app/bot.log " , " r " , encoding = " utf-8 " ) as f :
lines = f . readlines ( )
last_100 = lines [ - 100 : ] if len ( lines ) > = 100 else lines
return " " . join ( last_100 )
except Exception as e :
return f " Error reading log file: { e } "
@app.get ( " /prompt " )
def get_last_prompt ( ) :
return { " prompt " : globals . LAST_FULL_PROMPT or " No prompt has been issued yet. " }
@app.get ( " /mood " )
def get_current_mood ( ) :
return { " mood " : globals . DM_MOOD , " description " : globals . DM_MOOD_DESCRIPTION }
@app.post ( " /mood " )
async def set_mood_endpoint ( data : MoodSetRequest ) :
# This endpoint now operates on DM_MOOD
from utils . moods import MOOD_EMOJIS
if data . mood not in MOOD_EMOJIS :
return { " status " : " error " , " message " : f " Mood ' { data . mood } ' not recognized. Available moods: { ' , ' . join ( MOOD_EMOJIS . keys ( ) ) } " }
# Update DM mood (DMs don't have nicknames, so no nickname update needed)
globals . DM_MOOD = data . mood
from utils . moods import load_mood_description
globals . DM_MOOD_DESCRIPTION = load_mood_description ( data . mood )
return { " status " : " ok " , " new_mood " : data . mood }
@app.post ( " /mood/reset " )
async def reset_mood_endpoint ( ) :
# Reset DM mood to neutral (DMs don't have nicknames, so no nickname update needed)
globals . DM_MOOD = " neutral "
from utils . moods import load_mood_description
globals . DM_MOOD_DESCRIPTION = load_mood_description ( " neutral " )
return { " status " : " ok " , " new_mood " : " neutral " }
@app.post ( " /mood/calm " )
def calm_miku_endpoint ( ) :
# Calm DM mood to neutral (DMs don't have nicknames, so no nickname update needed)
globals . DM_MOOD = " neutral "
from utils . moods import load_mood_description
globals . DM_MOOD_DESCRIPTION = load_mood_description ( " neutral " )
return { " status " : " ok " , " message " : " Miku has been calmed down " }
2026-01-02 17:11:58 +02:00
# ========== Evil Mode Management ==========
@app.get ( " /evil-mode " )
def get_evil_mode_status ( ) :
""" Get current evil mode status """
from utils . evil_mode import is_evil_mode , get_current_evil_mood
evil_mode = is_evil_mode ( )
if evil_mode :
mood , mood_desc = get_current_evil_mood ( )
return {
" evil_mode " : True ,
" mood " : mood ,
" description " : mood_desc ,
" available_moods " : globals . EVIL_AVAILABLE_MOODS
}
return {
" evil_mode " : False ,
" mood " : None ,
" description " : None ,
" available_moods " : globals . EVIL_AVAILABLE_MOODS
}
@app.post ( " /evil-mode/enable " )
def enable_evil_mode ( ) :
""" Enable evil mode """
from utils . evil_mode import apply_evil_mode_changes
if globals . EVIL_MODE :
return { " status " : " ok " , " message " : " Evil mode is already enabled " , " evil_mode " : True }
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
globals . client . loop . create_task ( apply_evil_mode_changes ( globals . client ) )
return { " status " : " ok " , " message " : " Evil mode enabled " , " evil_mode " : True }
else :
return { " status " : " error " , " message " : " Discord client not ready " }
@app.post ( " /evil-mode/disable " )
def disable_evil_mode ( ) :
""" Disable evil mode """
from utils . evil_mode import revert_evil_mode_changes
if not globals . EVIL_MODE :
return { " status " : " ok " , " message " : " Evil mode is already disabled " , " evil_mode " : False }
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
globals . client . loop . create_task ( revert_evil_mode_changes ( globals . client ) )
return { " status " : " ok " , " message " : " Evil mode disabled " , " evil_mode " : False }
else :
return { " status " : " error " , " message " : " Discord client not ready " }
@app.post ( " /evil-mode/toggle " )
def toggle_evil_mode ( ) :
""" Toggle evil mode on/off """
from utils . evil_mode import apply_evil_mode_changes , revert_evil_mode_changes
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Discord client not ready " }
if globals . EVIL_MODE :
globals . client . loop . create_task ( revert_evil_mode_changes ( globals . client ) )
return { " status " : " ok " , " message " : " Evil mode disabled " , " evil_mode " : False }
else :
globals . client . loop . create_task ( apply_evil_mode_changes ( globals . client ) )
return { " status " : " ok " , " message " : " Evil mode enabled " , " evil_mode " : True }
@app.get ( " /evil-mode/mood " )
def get_evil_mood ( ) :
""" Get current evil mood """
from utils . evil_mode import get_current_evil_mood
mood , mood_desc = get_current_evil_mood ( )
return {
" mood " : mood ,
" description " : mood_desc ,
" available_moods " : globals . EVIL_AVAILABLE_MOODS
}
@app.post ( " /evil-mode/mood " )
def set_evil_mood_endpoint ( data : EvilMoodSetRequest ) :
""" Set evil mood """
from utils . evil_mode import set_evil_mood , is_valid_evil_mood , update_all_evil_nicknames
if not is_valid_evil_mood ( data . mood ) :
return {
" status " : " error " ,
" message " : f " Mood ' { data . mood } ' not recognized. Available evil moods: { ' , ' . join ( globals . EVIL_AVAILABLE_MOODS ) } "
}
success = set_evil_mood ( data . mood )
if success :
# Update nicknames if evil mode is active
if globals . EVIL_MODE and globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
globals . client . loop . create_task ( update_all_evil_nicknames ( globals . client ) )
return { " status " : " ok " , " new_mood " : data . mood }
return { " status " : " error " , " message " : " Failed to set evil mood " }
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
# ========== Bipolar Mode Management ==========
class BipolarTriggerRequest ( BaseModel ) :
channel_id : str # String to handle large Discord IDs from JS
message_id : str = None # Optional: starting message ID (string)
context : str = " "
@app.get ( " /bipolar-mode " )
def get_bipolar_mode_status ( ) :
""" Get current bipolar mode status """
from utils . bipolar_mode import is_bipolar_mode , is_argument_in_progress
# Get any active arguments
active_arguments = { }
for channel_id , data in globals . BIPOLAR_ARGUMENT_IN_PROGRESS . items ( ) :
if data . get ( " active " ) :
active_arguments [ channel_id ] = data
return {
" bipolar_mode " : is_bipolar_mode ( ) ,
" evil_mode " : globals . EVIL_MODE ,
" active_arguments " : active_arguments ,
" webhooks_configured " : len ( globals . BIPOLAR_WEBHOOKS )
}
@app.post ( " /bipolar-mode/enable " )
def enable_bipolar_mode ( ) :
""" Enable bipolar mode """
from utils . bipolar_mode import enable_bipolar_mode as _enable
if globals . BIPOLAR_MODE :
return { " status " : " ok " , " message " : " Bipolar mode is already enabled " , " bipolar_mode " : True }
_enable ( )
return { " status " : " ok " , " message " : " Bipolar mode enabled " , " bipolar_mode " : True }
@app.post ( " /bipolar-mode/disable " )
def disable_bipolar_mode ( ) :
""" Disable bipolar mode """
from utils . bipolar_mode import disable_bipolar_mode as _disable , cleanup_webhooks
if not globals . BIPOLAR_MODE :
return { " status " : " ok " , " message " : " Bipolar mode is already disabled " , " bipolar_mode " : False }
_disable ( )
# Optionally cleanup webhooks in background
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
globals . client . loop . create_task ( cleanup_webhooks ( globals . client ) )
return { " status " : " ok " , " message " : " Bipolar mode disabled " , " bipolar_mode " : False }
@app.post ( " /bipolar-mode/toggle " )
def toggle_bipolar_mode ( ) :
""" Toggle bipolar mode on/off """
from utils . bipolar_mode import toggle_bipolar_mode as _toggle , cleanup_webhooks
new_state = _toggle ( )
# If disabled, cleanup webhooks
if not new_state :
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
globals . client . loop . create_task ( cleanup_webhooks ( globals . client ) )
return {
" status " : " ok " ,
" message " : f " Bipolar mode { ' enabled ' if new_state else ' disabled ' } " ,
" bipolar_mode " : new_state
}
@app.post ( " /bipolar-mode/trigger-argument " )
def trigger_argument ( data : BipolarTriggerRequest ) :
""" Manually trigger an argument in a specific channel
If message_id is provided , the argument will start from that message .
The opposite persona will respond to it .
"""
from utils . bipolar_mode import force_trigger_argument , force_trigger_argument_from_message_id , is_bipolar_mode , is_argument_in_progress
# Parse IDs from strings
try :
channel_id = int ( data . channel_id )
except ValueError :
return { " status " : " error " , " message " : " Invalid channel ID format " }
message_id = None
if data . message_id :
try :
message_id = int ( data . message_id )
except ValueError :
return { " status " : " error " , " message " : " Invalid message ID format " }
if not is_bipolar_mode ( ) :
return { " status " : " error " , " message " : " Bipolar mode is not enabled " }
if is_argument_in_progress ( channel_id ) :
return { " status " : " error " , " message " : " An argument is already in progress in this channel " }
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Discord client not ready " }
# If message_id is provided, use the message-based trigger
if message_id :
import asyncio
async def trigger_from_message ( ) :
success , error = await force_trigger_argument_from_message_id (
channel_id , message_id , globals . client , data . context
)
if not success :
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 trigger argument from message: { error } " )
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
globals . client . loop . create_task ( trigger_from_message ( ) )
return {
" status " : " ok " ,
" message " : f " Argument triggered from message { message_id } " ,
" channel_id " : channel_id ,
" message_id " : message_id
}
# Otherwise, find the channel and trigger normally
channel = globals . client . get_channel ( channel_id )
if not channel :
return { " status " : " error " , " message " : f " Channel { channel_id } not found " }
# Trigger the argument
globals . client . loop . create_task ( force_trigger_argument ( channel , globals . client , data . context ) )
return {
" status " : " ok " ,
" message " : f " Argument triggered in # { channel . name } " ,
" channel_id " : channel_id
}
2026-01-09 00:03:59 +02:00
@app.post ( " /bipolar-mode/trigger-dialogue " )
def trigger_dialogue ( data : dict ) :
""" Manually trigger a persona dialogue from a message
Forces the opposite persona to start a dialogue ( bypasses the interjection check ) .
"""
from utils . persona_dialogue import get_dialogue_manager
from utils . bipolar_mode import is_bipolar_mode , is_argument_in_progress
message_id_str = data . get ( " message_id " )
if not message_id_str :
return { " status " : " error " , " message " : " Message ID is required " }
# Parse message ID
try :
message_id = int ( message_id_str )
except ValueError :
return { " status " : " error " , " message " : " Invalid message ID format " }
if not is_bipolar_mode ( ) :
return { " status " : " error " , " message " : " Bipolar mode is not enabled " }
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Discord client not ready " }
import asyncio
async def trigger_dialogue_task ( ) :
try :
# Fetch the message
message = None
for channel in globals . client . get_all_channels ( ) :
if hasattr ( channel , ' fetch_message ' ) :
try :
message = await channel . fetch_message ( message_id )
break
except :
continue
if not message :
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 " Message { message_id } not found " )
2026-01-09 00:03:59 +02:00
return
# Check if there's already an argument or dialogue in progress
dialogue_manager = get_dialogue_manager ( )
if dialogue_manager . is_dialogue_active ( message . channel . 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 . error ( f " Dialogue already active in channel { message . channel . id } " )
2026-01-09 00:03:59 +02:00
return
if is_argument_in_progress ( message . channel . 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 . error ( f " Argument already in progress in channel { message . channel . id } " )
2026-01-09 00:03:59 +02:00
return
# Determine current persona from the message author
if message . webhook_id :
# It's a webhook message, need to determine which persona
current_persona = " evil " if globals . EVIL_MODE else " miku "
elif message . author . id == globals . client . user . id :
# It's the bot's message
current_persona = " evil " if globals . EVIL_MODE else " miku "
else :
# User message - can't trigger dialogue from user messages
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 " Cannot trigger dialogue from user message " )
2026-01-09 00:03:59 +02:00
return
opposite_persona = " evil " if current_persona == " miku " 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 . info ( f " [Manual Trigger] Forcing { opposite_persona } to start dialogue on message { message_id } " )
2026-01-09 00:03:59 +02:00
# Force start the dialogue (bypass interjection check)
dialogue_manager . start_dialogue ( message . channel . id )
asyncio . create_task (
dialogue_manager . handle_dialogue_turn (
message . channel ,
opposite_persona ,
trigger_reason = " manual_trigger "
)
)
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 triggering dialogue: { e } " )
2026-01-09 00:03:59 +02:00
import traceback
traceback . print_exc ( )
globals . client . loop . create_task ( trigger_dialogue_task ( ) )
return {
" status " : " ok " ,
" message " : f " Dialogue triggered for message { message_id } "
}
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
@app.get ( " /bipolar-mode/scoreboard " )
def get_bipolar_scoreboard ( ) :
""" Get the bipolar mode argument scoreboard """
from utils . bipolar_mode import load_scoreboard , get_scoreboard_summary
scoreboard = load_scoreboard ( )
return {
" status " : " ok " ,
" scoreboard " : {
" miku_wins " : scoreboard . get ( " miku " , 0 ) ,
" evil_wins " : scoreboard . get ( " evil " , 0 ) ,
" total_arguments " : scoreboard . get ( " miku " , 0 ) + scoreboard . get ( " evil " , 0 ) ,
" history " : scoreboard . get ( " history " , [ ] ) [ - 10 : ] # Last 10 results
} ,
" summary " : get_scoreboard_summary ( )
}
@app.post ( " /bipolar-mode/cleanup-webhooks " )
def cleanup_bipolar_webhooks ( ) :
""" Cleanup all bipolar webhooks from all servers """
from utils . bipolar_mode import cleanup_webhooks
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Discord client not ready " }
globals . client . loop . create_task ( cleanup_webhooks ( globals . client ) )
return { " status " : " ok " , " message " : " Webhook cleanup started " }
2026-01-09 00:03:59 +02:00
# ========== GPU Selection ==========
@app.get ( " /gpu-status " )
def get_gpu_status ( ) :
""" Get current GPU selection """
gpu_state_file = os . path . join ( os . path . dirname ( __file__ ) , " memory " , " gpu_state.json " )
try :
with open ( gpu_state_file , " r " ) as f :
state = json . load ( f )
return { " gpu " : state . get ( " current_gpu " , " nvidia " ) }
except :
return { " gpu " : " nvidia " }
@app.post ( " /gpu-select " )
async def select_gpu ( request : Request ) :
""" Select which GPU to use for inference """
data = await request . json ( )
gpu = data . get ( " gpu " , " nvidia " ) . lower ( )
if gpu not in [ " nvidia " , " amd " ] :
return { " status " : " error " , " message " : " Invalid GPU selection. Must be ' nvidia ' or ' amd ' " }
gpu_state_file = os . path . join ( os . path . dirname ( __file__ ) , " memory " , " gpu_state.json " )
try :
from datetime import datetime
state = {
" current_gpu " : gpu ,
" last_updated " : datetime . now ( ) . isoformat ( )
}
with open ( gpu_state_file , " w " ) as f :
json . dump ( state , f , indent = 2 )
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 " GPU Selection: Switched to { gpu . upper ( ) } GPU " )
2026-01-09 00:03:59 +02:00
return { " status " : " ok " , " message " : f " Switched to { gpu . upper ( ) } GPU " , " gpu " : gpu }
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 " GPU Selection Error: { e } " )
2026-01-09 00:03:59 +02:00
return { " status " : " error " , " message " : str ( e ) }
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
@app.get ( " /bipolar-mode/arguments " )
def get_active_arguments ( ) :
""" Get all active arguments """
active = { }
for channel_id , data in globals . BIPOLAR_ARGUMENT_IN_PROGRESS . items ( ) :
if data . get ( " active " ) :
channel = globals . client . get_channel ( channel_id ) if globals . client else None
active [ channel_id ] = {
* * data ,
" channel_name " : channel . name if channel else " Unknown "
}
return { " active_arguments " : active }
2025-12-07 17:15:09 +02:00
# ========== Per-Server Mood Management ==========
@app.get ( " /servers/ {guild_id} /mood " )
def get_server_mood ( guild_id : int ) :
""" Get current mood for a specific server """
mood_name , mood_description = server_manager . get_server_mood ( guild_id )
return {
" guild_id " : guild_id ,
" mood " : mood_name ,
" description " : mood_description
}
@app.post ( " /servers/ {guild_id} /mood " )
async def set_server_mood_endpoint ( guild_id : int , data : MoodSetRequest ) :
""" Set mood for a specific server """
# Check if server exists
if guild_id not in server_manager . servers :
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 " Server { guild_id } not found in server_manager.servers " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : " Server not found " }
# Check if mood is valid
from utils . moods import MOOD_EMOJIS
if data . mood not in MOOD_EMOJIS :
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 " Mood ' { data . mood } ' not found in MOOD_EMOJIS. Available moods: { list ( MOOD_EMOJIS . keys ( ) ) } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Mood ' { data . mood } ' not recognized. Available moods: { ' , ' . join ( MOOD_EMOJIS . keys ( ) ) } " }
success = server_manager . set_server_mood ( guild_id , data . mood )
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 " Server mood set result: { success } " )
2025-12-07 17:15:09 +02:00
if success :
# V2: Notify autonomous engine of mood change
try :
from utils . autonomous import on_mood_change
on_mood_change ( guild_id , data . mood )
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 notify autonomous engine of mood change: { e } " )
2025-12-07 17:15:09 +02:00
# Update the nickname for this server
from utils . moods import update_server_nickname
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 " Updating nickname for server { guild_id } " )
2025-12-07 17:15:09 +02:00
globals . client . loop . create_task ( update_server_nickname ( guild_id ) )
return { " status " : " ok " , " new_mood " : data . mood , " guild_id " : 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 . warning ( f " set_server_mood returned False for unknown reason " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : " Failed to set server mood " }
@app.post ( " /servers/ {guild_id} /mood/reset " )
async def reset_server_mood_endpoint ( guild_id : int ) :
""" Reset mood to neutral for a specific server """
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 " Resetting mood for server { guild_id } to neutral " )
2025-12-07 17:15:09 +02:00
# Check if server exists
if guild_id not in server_manager . servers :
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 " Server { guild_id } not found in server_manager.servers " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : " Server not found " }
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 " Server validation passed, calling set_server_mood " )
2025-12-07 17:15:09 +02:00
success = server_manager . set_server_mood ( guild_id , " neutral " )
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 " Server mood reset result: { success } " )
2025-12-07 17:15:09 +02:00
if success :
# V2: Notify autonomous engine of mood change
try :
from utils . autonomous import on_mood_change
on_mood_change ( guild_id , " neutral " )
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 notify autonomous engine of mood reset: { e } " )
2025-12-07 17:15:09 +02:00
# Update the nickname for this server
from utils . moods import update_server_nickname
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 " Updating nickname for server { guild_id } " )
2025-12-07 17:15:09 +02:00
globals . client . loop . create_task ( update_server_nickname ( guild_id ) )
return { " status " : " ok " , " new_mood " : " neutral " , " guild_id " : 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 . warning ( f " set_server_mood returned False for unknown reason " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : " Failed to reset server mood " }
@app.get ( " /servers/ {guild_id} /mood/state " )
def get_server_mood_state ( guild_id : int ) :
""" Get complete mood state for a specific server """
mood_state = server_manager . get_server_mood_state ( guild_id )
if mood_state :
return { " status " : " ok " , " guild_id " : guild_id , " mood_state " : mood_state }
return { " status " : " error " , " message " : " Server not found " }
@app.post ( " /conversation/reset " )
def reset_convo ( data : ConversationResetRequest ) :
reset_conversation ( data . user_id )
return { " status " : " ok " , " message " : " Conversation reset " }
@app.post ( " /sleep " )
async def force_sleep_endpoint ( ) :
await force_sleep ( )
return { " status " : " ok " , " message " : " Miku is now sleeping " }
@app.post ( " /wake " )
async def wake_up_endpoint ( ) :
await wake_up ( )
return { " status " : " ok " , " message " : " Miku is now awake " }
@app.post ( " /bedtime " )
async def bedtime_endpoint ( guild_id : int = None ) :
# If guild_id is provided, send bedtime reminder only to that server
# If no guild_id, send to all servers (legacy behavior)
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Send to specific server only
from utils . scheduled import send_bedtime_reminder_for_server
globals . client . loop . create_task ( send_bedtime_reminder_for_server ( guild_id , globals . client ) )
return { " status " : " ok " , " message " : f " Bedtime reminder queued for server { guild_id } " }
else :
# Send to all servers (legacy behavior)
from utils . scheduled import send_bedtime_now
globals . client . loop . create_task ( send_bedtime_now ( ) )
return { " status " : " ok " , " message " : " Bedtime reminder queued for all servers " }
else :
return { " status " : " error " , " message " : " Bot not ready " }
@app.post ( " /autonomous/general " )
async def trigger_autonomous_general ( guild_id : int = None ) :
# If guild_id is provided, send autonomous message only to that server
# If no guild_id, send to all servers (legacy behavior)
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Send to specific server only
from utils . autonomous import miku_say_something_general_for_server
globals . client . loop . create_task ( miku_say_something_general_for_server ( guild_id ) )
return { " status " : " ok " , " message " : f " Autonomous general message queued for server { guild_id } " }
else :
# Send to all servers (legacy behavior)
from utils . autonomous import miku_say_something_general
globals . client . loop . create_task ( miku_say_something_general ( ) )
return { " status " : " ok " , " message " : " Autonomous general message queued for all servers " }
else :
return { " status " : " error " , " message " : " Bot not ready " }
@app.post ( " /autonomous/engage " )
2025-12-16 23:13:19 +02:00
async def trigger_autonomous_engage_user ( guild_id : int = None , user_id : str = None , engagement_type : str = None ) :
2025-12-07 17:15:09 +02:00
# If guild_id is provided, send autonomous engagement only to that server
# If no guild_id, send to all servers (legacy behavior)
2025-12-16 23:13:19 +02:00
# user_id: Optional specific user to engage (Discord user ID as string)
# engagement_type: Optional type - 'activity', 'general', 'status', or None for random
2025-12-07 17:15:09 +02:00
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Send to specific server only
from utils . autonomous import miku_engage_random_user_for_server
2025-12-16 23:13:19 +02:00
globals . client . loop . create_task ( miku_engage_random_user_for_server ( guild_id , user_id = user_id , engagement_type = engagement_type ) )
# Build detailed message
msg_parts = [ f " Autonomous user engagement queued for server { guild_id } " ]
if user_id :
msg_parts . append ( f " targeting user { user_id } " )
if engagement_type :
msg_parts . append ( f " with { engagement_type } engagement " )
return { " status " : " ok " , " message " : " " . join ( msg_parts ) }
2025-12-07 17:15:09 +02:00
else :
# Send to all servers (legacy behavior)
from utils . autonomous import miku_engage_random_user
2025-12-16 23:13:19 +02:00
globals . client . loop . create_task ( miku_engage_random_user ( user_id = user_id , engagement_type = engagement_type ) )
msg_parts = [ " Autonomous user engagement queued for all servers " ]
if user_id :
msg_parts . append ( f " targeting user { user_id } " )
if engagement_type :
msg_parts . append ( f " with { engagement_type } engagement " )
return { " status " : " ok " , " message " : " " . join ( msg_parts ) }
2025-12-07 17:15:09 +02:00
else :
return { " status " : " error " , " message " : " Bot not ready " }
@app.post ( " /autonomous/tweet " )
async def trigger_autonomous_tweet ( guild_id : int = None ) :
# If guild_id is provided, send tweet only to that server
# If no guild_id, send to all servers (legacy behavior)
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Send to specific server only
from utils . autonomous import share_miku_tweet_for_server
globals . client . loop . create_task ( share_miku_tweet_for_server ( guild_id ) )
return { " status " : " ok " , " message " : f " Autonomous tweet sharing queued for server { guild_id } " }
else :
# Send to all servers (legacy behavior)
from utils . autonomous import share_miku_tweet
globals . client . loop . create_task ( share_miku_tweet ( ) )
return { " status " : " ok " , " message " : " Autonomous tweet sharing queued for all servers " }
else :
return { " status " : " error " , " message " : " Bot not ready " }
@app.post ( " /autonomous/custom " )
async def custom_autonomous_message ( req : CustomPromptRequest , guild_id : int = None ) :
# If guild_id is provided, send custom prompt only to that server
# If no guild_id, send to all servers (legacy behavior)
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Send to specific server only
from utils . autonomous import handle_custom_prompt_for_server
# Use create_task to avoid timeout context manager error
globals . client . loop . create_task ( handle_custom_prompt_for_server ( guild_id , req . prompt ) )
return { " status " : " ok " , " message " : f " Custom autonomous message queued for server { guild_id } " }
else :
# Send to all servers (legacy behavior)
from utils . autonomous import handle_custom_prompt
# Use create_task to avoid timeout context manager error
globals . client . loop . create_task ( handle_custom_prompt ( req . prompt ) )
return { " status " : " ok " , " message " : " Custom autonomous message queued for all servers " }
else :
return { " status " : " error " , " message " : " Bot not ready " }
@app.post ( " /autonomous/reaction " )
async def trigger_autonomous_reaction ( guild_id : int = None ) :
# If guild_id is provided, trigger reaction only for that server
# If no guild_id, trigger for all servers (legacy behavior)
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Trigger for specific server only (force=True bypasses 50% chance)
from utils . autonomous import miku_autonomous_reaction_for_server
globals . client . loop . create_task ( miku_autonomous_reaction_for_server ( guild_id , force = True ) )
return { " status " : " ok " , " message " : f " Autonomous reaction queued for server { guild_id } " }
else :
# Trigger for all servers (legacy behavior, force=True bypasses 50% chance)
from utils . autonomous import miku_autonomous_reaction
globals . client . loop . create_task ( miku_autonomous_reaction ( force = True ) )
return { " status " : " ok " , " message " : " Autonomous reaction queued for all servers " }
else :
return { " status " : " error " , " message " : " Bot not ready " }
2025-12-10 14:57:59 +02:00
@app.post ( " /autonomous/join-conversation " )
async def trigger_detect_and_join_conversation ( guild_id : int = None ) :
# If guild_id is provided, detect and join conversation only for that server
# If no guild_id, trigger for all servers
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 " Join conversation endpoint called with guild_id= { guild_id } " )
2025-12-10 14:57:59 +02:00
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
if guild_id is not None :
# Trigger for specific server only (force=True to bypass checks when manually triggered)
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 " Importing and calling miku_detect_and_join_conversation_for_server( { guild_id } , force=True) " )
2025-12-10 14:57:59 +02:00
from utils . autonomous import miku_detect_and_join_conversation_for_server
globals . client . loop . create_task ( miku_detect_and_join_conversation_for_server ( guild_id , force = True ) )
return { " status " : " ok " , " message " : f " Detect and join conversation queued for server { guild_id } " }
else :
# Trigger for all servers (force=True to bypass checks when manually triggered)
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 " Importing and calling miku_detect_and_join_conversation() for all servers " )
2025-12-10 14:57:59 +02:00
from utils . autonomous import miku_detect_and_join_conversation
globals . client . loop . create_task ( miku_detect_and_join_conversation ( force = True ) )
return { " status " : " ok " , " message " : " Detect and join conversation queued for all servers " }
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 " Bot not ready: client= { globals . client } , loop= { globals . client . loop if globals . client else None } " )
2025-12-10 14:57:59 +02:00
return { " status " : " error " , " message " : " Bot not ready " }
2025-12-07 17:15:09 +02:00
@app.post ( " /profile-picture/change " )
async def trigger_profile_picture_change (
guild_id : int = None ,
file : UploadFile = File ( None )
) :
"""
Change Miku ' s profile picture.
If a file is provided , use it . Otherwise , search Danbooru .
"""
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Bot not ready " }
try :
from utils . profile_picture_manager import profile_picture_manager
from server_manager import server_manager
# Get mood from guild_id (if provided)
mood = None
if guild_id is not None :
mood , _ = server_manager . get_server_mood ( guild_id )
else :
# Use DM mood as fallback
mood = globals . DM_MOOD
# If file provided, use it
custom_image_bytes = None
if file :
custom_image_bytes = await file . read ( )
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 " Received custom image upload ( { len ( custom_image_bytes ) } bytes) " )
2025-12-07 17:15:09 +02:00
# Change profile picture
result = await profile_picture_manager . change_profile_picture (
mood = mood ,
custom_image_bytes = custom_image_bytes ,
debug = True
)
if result [ " success " ] :
return {
" status " : " ok " ,
" message " : " Profile picture changed successfully " ,
" source " : result [ " source " ] ,
" metadata " : result . get ( " metadata " , { } )
}
else :
return {
" status " : " error " ,
" message " : result . get ( " error " , " Unknown error " ) ,
" source " : result [ " source " ]
}
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 profile picture API: { e } " )
2025-12-07 17:15:09 +02:00
import traceback
traceback . print_exc ( )
return { " status " : " error " , " message " : f " Unexpected error: { str ( e ) } " }
@app.get ( " /profile-picture/metadata " )
async def get_profile_picture_metadata ( ) :
""" Get metadata about the current profile picture """
try :
from utils . profile_picture_manager import profile_picture_manager
metadata = profile_picture_manager . load_metadata ( )
if metadata :
return { " status " : " ok " , " metadata " : metadata }
else :
return { " status " : " ok " , " metadata " : None , " message " : " No metadata found " }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.post ( " /profile-picture/restore-fallback " )
async def restore_fallback_profile_picture ( ) :
""" Restore the original fallback profile picture """
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Bot not ready " }
try :
from utils . profile_picture_manager import profile_picture_manager
success = await profile_picture_manager . restore_fallback ( )
if success :
return { " status " : " ok " , " message " : " Fallback profile picture restored " }
else :
return { " status " : " error " , " message " : " Failed to restore fallback " }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.post ( " /role-color/custom " )
async def set_custom_role_color ( hex_color : str = Form ( . . . ) ) :
""" Set a custom role color across all servers """
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Bot not ready " }
try :
from utils . profile_picture_manager import profile_picture_manager
result = await profile_picture_manager . set_custom_role_color ( hex_color , debug = True )
if result [ " success " ] :
return {
" status " : " ok " ,
" message " : f " Role color updated to { result [ ' color ' ] [ ' hex ' ] } " ,
" color " : result [ " color " ]
}
else :
return { " status " : " error " , " message " : result . get ( " error " , " Unknown error " ) }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.post ( " /role-color/reset-fallback " )
async def reset_role_color_to_fallback ( ) :
""" Reset role color to fallback (#86cecb) """
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Bot not ready " }
try :
from utils . profile_picture_manager import profile_picture_manager
result = await profile_picture_manager . reset_to_fallback_color ( debug = True )
if result [ " success " ] :
return {
" status " : " ok " ,
" message " : f " Role color reset to fallback { result [ ' color ' ] [ ' hex ' ] } " ,
" color " : result [ " color " ]
}
else :
return { " status " : " error " , " message " : " Failed to reset color " }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.post ( " /manual/send " )
async def manual_send (
message : str = Form ( . . . ) ,
channel_id : str = Form ( . . . ) ,
2025-12-14 16:41:02 +02:00
files : List [ UploadFile ] = File ( default = [ ] ) ,
reply_to_message_id : str = Form ( None ) ,
mention_author : bool = Form ( True )
2025-12-07 17:15:09 +02:00
) :
try :
channel = globals . client . get_channel ( int ( channel_id ) )
if not channel :
return { " status " : " error " , " message " : " Channel not found " }
# Read file content immediately before the request closes
file_data = [ ]
for file in files :
try :
file_content = await file . read ( )
file_data . append ( {
' filename ' : file . filename ,
' content ' : file_content
} )
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 read file { file . filename } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to read file { file . filename } : { e } " }
# Use create_task to avoid timeout context manager error
async def send_message_and_files ( ) :
try :
2025-12-14 16:41:02 +02:00
# Get the reference message if replying (must be done inside the task)
reference_message = None
if reply_to_message_id :
try :
reference_message = await channel . fetch_message ( int ( reply_to_message_id ) )
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 " Could not fetch message { reply_to_message_id } for reply: { e } " )
2025-12-14 16:41:02 +02:00
return
2025-12-07 17:15:09 +02:00
# Send the main message
if message . strip ( ) :
2025-12-14 16:41:02 +02:00
if reference_message :
await channel . send ( message , reference = reference_message , mention_author = mention_author )
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 " Manual message sent as reply to # { channel . name } " )
2025-12-14 16:41:02 +02:00
else :
await channel . send ( message )
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 " Manual message sent to # { channel . name } " )
2025-12-07 17:15:09 +02:00
# Send files if any
for file_info in file_data :
try :
await channel . send ( file = discord . File ( io . BytesIO ( file_info [ ' content ' ] ) , filename = file_info [ ' filename ' ] ) )
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 " File { file_info [ ' filename ' ] } sent to # { channel . name } " )
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 send file { file_info [ ' filename ' ] } : { e } " )
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 send message: { e } " )
2025-12-07 17:15:09 +02:00
globals . client . loop . create_task ( send_message_and_files ( ) )
return { " status " : " ok " , " message " : " Message and files queued for sending " }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
2026-01-07 10:21:46 +02:00
@app.post ( " /manual/send-webhook " )
async def manual_send_webhook (
message : str = Form ( . . . ) ,
channel_id : str = Form ( . . . ) ,
persona : str = Form ( " miku " ) , # "miku" or "evil"
files : List [ UploadFile ] = File ( default = [ ] ) ,
reply_to_message_id : str = Form ( None ) ,
mention_author : bool = Form ( True )
) :
""" Send a manual message via webhook as either Hatsune Miku or Evil Miku """
try :
from utils . bipolar_mode import get_or_create_webhooks_for_channel , get_miku_display_name , get_evil_miku_display_name
channel = globals . client . get_channel ( int ( channel_id ) )
if not channel :
return { " status " : " error " , " message " : " Channel not found " }
# Validate persona
if persona not in [ " miku " , " evil " ] :
return { " status " : " error " , " message " : " Invalid persona. Must be ' miku ' or ' evil ' " }
# Read file content immediately before the request closes
file_data = [ ]
for file in files :
try :
file_content = await file . read ( )
file_data . append ( {
' filename ' : file . filename ,
' content ' : file_content
} )
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 read file { file . filename } : { e } " )
2026-01-07 10:21:46 +02:00
return { " status " : " error " , " message " : f " Failed to read file { file . filename } : { e } " }
# Use create_task to avoid timeout context manager error
async def send_webhook_message ( ) :
try :
2026-01-07 13:44:13 +02:00
# Get or create webhooks for this channel (inside the task)
webhooks = await get_or_create_webhooks_for_channel ( channel )
if not webhooks :
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 create webhooks for channel # { channel . name } " )
2026-01-07 13:44:13 +02:00
return
# Select the appropriate webhook
webhook = webhooks [ " evil_miku " ] if persona == " evil " else webhooks [ " miku " ]
display_name = get_evil_miku_display_name ( ) if persona == " evil " else get_miku_display_name ( )
2026-01-07 10:21:46 +02:00
# Prepare files for webhook
discord_files = [ ]
for file_info in file_data :
discord_files . append ( discord . File ( io . BytesIO ( file_info [ ' content ' ] ) , filename = file_info [ ' filename ' ] ) )
# Send via webhook with display name
2026-01-07 13:44:13 +02:00
if discord_files :
await webhook . send (
content = message ,
username = display_name ,
files = discord_files ,
wait = True
)
else :
await webhook . send (
content = message ,
username = display_name ,
wait = True
)
2026-01-07 10:21:46 +02:00
persona_name = " Evil Miku " if persona == " evil " else " Hatsune 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 . info ( f " Manual webhook message sent as { persona_name } to # { channel . name } " )
2026-01-07 10:21:46 +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 send webhook message: { e } " )
2026-01-07 13:44:13 +02:00
import traceback
traceback . print_exc ( )
2026-01-07 10:21:46 +02:00
globals . client . loop . create_task ( send_webhook_message ( ) )
return { " status " : " ok " , " message " : f " Webhook message queued for sending as { persona } " }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
2025-12-07 17:15:09 +02:00
@app.get ( " /status " )
def status ( ) :
# Get per-server mood summary
server_moods = { }
for guild_id in server_manager . servers :
mood_name , _ = server_manager . get_server_mood ( guild_id )
server_moods [ str ( guild_id ) ] = mood_name
return {
" status " : " online " ,
" mood " : globals . DM_MOOD ,
" servers " : len ( server_manager . servers ) ,
" active_schedulers " : len ( server_manager . schedulers ) ,
" server_moods " : server_moods
}
@app.get ( " /autonomous/stats " )
def get_autonomous_stats ( ) :
""" Get autonomous engine stats for all servers """
from utils . autonomous import autonomous_engine
stats = { }
for guild_id in server_manager . servers :
server_info = server_manager . servers [ guild_id ]
mood_name , _ = server_manager . get_server_mood ( guild_id )
# Get context signals for this server
if guild_id in autonomous_engine . server_contexts :
ctx = autonomous_engine . server_contexts [ guild_id ]
# Get mood profile
mood_profile = autonomous_engine . mood_profiles . get ( mood_name , {
" energy " : 0.5 ,
" sociability " : 0.5 ,
" impulsiveness " : 0.5
} )
# Sanitize float values for JSON serialization (replace inf with large number)
time_since_action = ctx . time_since_last_action
if time_since_action == float ( ' inf ' ) :
time_since_action = 999999
time_since_interaction = ctx . time_since_last_interaction
if time_since_interaction == float ( ' inf ' ) :
time_since_interaction = 999999
stats [ str ( guild_id ) ] = {
" guild_name " : server_info . guild_name ,
" mood " : mood_name ,
" mood_profile " : mood_profile ,
" context " : {
" messages_last_5min " : ctx . messages_last_5min ,
" messages_last_hour " : ctx . messages_last_hour ,
" unique_users_active " : ctx . unique_users_active ,
" conversation_momentum " : round ( ctx . conversation_momentum , 2 ) ,
" users_joined_recently " : ctx . users_joined_recently ,
" users_status_changed " : ctx . users_status_changed ,
" users_started_activity " : ctx . users_started_activity ,
" time_since_last_action " : round ( time_since_action , 1 ) ,
" time_since_last_interaction " : round ( time_since_interaction , 1 ) ,
" messages_since_last_appearance " : ctx . messages_since_last_appearance ,
" hour_of_day " : ctx . hour_of_day ,
" is_weekend " : ctx . is_weekend ,
" mood_energy_level " : round ( ctx . mood_energy_level , 2 )
}
}
else :
# Server not yet initialized in autonomous engine
mood_profile = autonomous_engine . mood_profiles . get ( mood_name , {
" energy " : 0.5 ,
" sociability " : 0.5 ,
" impulsiveness " : 0.5
} )
stats [ str ( guild_id ) ] = {
" guild_name " : server_info . guild_name ,
" mood " : mood_name ,
" mood_profile " : mood_profile ,
" context " : None
}
return { " servers " : stats }
@app.get ( " /conversation/ {user_id} " )
def get_conversation ( user_id : str ) :
if user_id in globals . conversation_history :
return { " conversation " : list ( globals . conversation_history [ user_id ] ) }
return { " conversation " : [ ] }
# ========== Figurine DM Subscription APIs ==========
@app.get ( " /figurines/subscribers " )
async def get_figurine_subscribers ( ) :
subs = figurine_load_subscribers ( )
return { " subscribers " : [ str ( uid ) for uid in subs ] }
@app.post ( " /figurines/subscribers " )
async def add_figurine_subscriber ( user_id : str = Form ( . . . ) ) :
try :
uid = int ( user_id )
ok = figurine_add_subscriber ( uid )
return { " status " : " ok " , " added " : ok }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.delete ( " /figurines/subscribers/ {user_id} " )
async def delete_figurine_subscriber ( user_id : str ) :
try :
uid = int ( user_id )
ok = figurine_remove_subscriber ( uid )
return { " status " : " ok " , " removed " : ok }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.post ( " /figurines/send_now " )
async def figurines_send_now ( tweet_url : str = Form ( None ) ) :
""" Trigger immediate figurine DM send to all subscribers, optionally with specific tweet URL """
if globals . client and globals . client . loop and globals . client . loop . is_running ( ) :
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 " Sending figurine DMs to all subscribers, tweet_url: { tweet_url } " )
2025-12-07 17:15:09 +02:00
globals . client . loop . create_task ( send_figurine_dm_to_all_subscribers ( globals . client , tweet_url = tweet_url ) )
return { " status " : " ok " , " message " : " Figurine DMs queued " }
return { " status " : " error " , " message " : " Bot not ready " }
@app.post ( " /figurines/send_to_user " )
async def figurines_send_to_user ( user_id : str = Form ( . . . ) , tweet_url : str = Form ( None ) ) :
""" Send figurine DM to a specific user, optionally with specific tweet 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 . debug ( f " Received figurine send request - user_id: ' { user_id } ' , tweet_url: ' { tweet_url } ' " )
2025-12-07 17:15:09 +02:00
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
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 ( " Bot not ready " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : " Bot not ready " }
try :
user_id_int = int ( 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 . debug ( f " Parsed user_id as { user_id_int } " )
2025-12-07 17:15:09 +02:00
except ValueError :
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 " Invalid user ID: ' { user_id } ' " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : " Invalid user ID " }
# Clean up tweet URL if it's empty string
if tweet_url == " " :
tweet_url = None
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 " Sending figurine DM to user { user_id_int } , tweet_url: { tweet_url } " )
2025-12-07 17:15:09 +02:00
# Queue the DM send task in the bot's event loop
globals . client . loop . create_task ( send_figurine_dm_to_single_user ( globals . client , user_id_int , tweet_url = tweet_url ) )
return { " status " : " ok " , " message " : f " Figurine DM to user { user_id } queued " }
# ========== Server Management Endpoints ==========
@app.get ( " /servers " )
def get_servers ( ) :
""" Get all configured servers """
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 ( " /servers endpoint called " )
logger . debug ( f " server_manager.servers keys: { list ( server_manager . servers . keys ( ) ) } " )
logger . debug ( f " server_manager.servers count: { len ( server_manager . servers ) } " )
2025-12-07 17:15:09 +02:00
# Debug: Check config file directly
config_file = server_manager . config_file
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 " Config file path: { config_file } " )
2025-12-07 17:15:09 +02:00
if os . path . exists ( config_file ) :
try :
with open ( config_file , " r " , encoding = " utf-8 " ) as f :
config_data = json . load ( f )
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 " Config file contains: { list ( config_data . keys ( ) ) } " )
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 read config file: { e } " )
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 ( " Config file does not exist " )
2025-12-07 17:15:09 +02:00
servers = [ ]
for server in server_manager . get_all_servers ( ) :
server_data = server . to_dict ( )
# Convert set to list for JSON serialization
server_data [ ' enabled_features ' ] = list ( server_data [ ' enabled_features ' ] )
# Convert guild_id to string to prevent JavaScript integer precision loss
server_data [ ' guild_id ' ] = str ( server_data [ ' guild_id ' ] )
servers . append ( server_data )
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 " Adding server to response: { server_data [ ' guild_id ' ] } - { server_data [ ' guild_name ' ] } " )
logger . debug ( f " Server data type check - guild_id: { type ( server_data [ ' guild_id ' ] ) } , value: { server_data [ ' guild_id ' ] } " )
2025-12-07 17:15:09 +02:00
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 " Returning { len ( servers ) } servers " )
2025-12-07 17:15:09 +02:00
return { " servers " : servers }
@app.post ( " /servers " )
def add_server ( data : ServerConfigRequest ) :
""" Add a new server configuration """
enabled_features = set ( data . enabled_features ) if data . enabled_features else None
success = server_manager . add_server (
guild_id = data . guild_id ,
guild_name = data . guild_name ,
autonomous_channel_id = data . autonomous_channel_id ,
autonomous_channel_name = data . autonomous_channel_name ,
bedtime_channel_ids = data . bedtime_channel_ids ,
enabled_features = enabled_features
)
if success :
# Restart schedulers to include the new server
server_manager . stop_all_schedulers ( )
server_manager . start_all_schedulers ( globals . client )
return { " status " : " ok " , " message " : f " Server { data . guild_name } added successfully " }
else :
return { " status " : " error " , " message " : " Failed to add server " }
@app.delete ( " /servers/ {guild_id} " )
def remove_server ( guild_id : int ) :
""" Remove a server configuration """
success = server_manager . remove_server ( guild_id )
if success :
return { " status " : " ok " , " message " : " Server removed successfully " }
else :
return { " status " : " error " , " message " : " Failed to remove server " }
@app.put ( " /servers/ {guild_id} " )
def update_server ( guild_id : int , data : dict ) :
""" Update server configuration """
success = server_manager . update_server_config ( guild_id , * * data )
if success :
# Restart schedulers to apply changes
server_manager . stop_all_schedulers ( )
server_manager . start_all_schedulers ( globals . client )
return { " status " : " ok " , " message " : " Server configuration updated " }
else :
return { " status " : " error " , " message " : " Failed to update server configuration " }
@app.post ( " /servers/ {guild_id} /bedtime-range " )
def update_server_bedtime_range ( guild_id : int , data : dict ) :
""" Update server bedtime range configuration """
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 " Updating bedtime range for server { guild_id } : { data } " )
2025-12-07 17:15:09 +02:00
# Validate the data
required_fields = [ ' bedtime_hour ' , ' bedtime_minute ' , ' bedtime_hour_end ' , ' bedtime_minute_end ' ]
for field in required_fields :
if field not in data :
return { " status " : " error " , " message " : f " Missing required field: { field } " }
# Validate time ranges
try :
bedtime_hour = int ( data [ ' bedtime_hour ' ] )
bedtime_minute = int ( data [ ' bedtime_minute ' ] )
bedtime_hour_end = int ( data [ ' bedtime_hour_end ' ] )
bedtime_minute_end = int ( data [ ' bedtime_minute_end ' ] )
# Basic validation
if not ( 0 < = bedtime_hour < = 23 ) or not ( 0 < = bedtime_hour_end < = 23 ) :
return { " status " : " error " , " message " : " Hours must be between 0 and 23 " }
if not ( 0 < = bedtime_minute < = 59 ) or not ( 0 < = bedtime_minute_end < = 59 ) :
return { " status " : " error " , " message " : " Minutes must be between 0 and 59 " }
except ( ValueError , TypeError ) :
return { " status " : " error " , " message " : " Invalid time values provided " }
# Update the server configuration
success = server_manager . update_server_config ( guild_id , * * data )
if success :
# Update just the bedtime job for this server (avoid restarting all schedulers)
job_success = server_manager . update_server_bedtime_job ( guild_id , globals . client )
if job_success :
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 " Bedtime range updated for server { guild_id } " )
2025-12-07 17:15:09 +02:00
return {
" status " : " ok " ,
" message " : f " Bedtime range updated: { bedtime_hour : 02d } : { bedtime_minute : 02d } - { bedtime_hour_end : 02d } : { bedtime_minute_end : 02d } "
}
else :
return { " status " : " error " , " message " : " Updated config but failed to update scheduler " }
else :
return { " status " : " error " , " message " : " Failed to update bedtime range " }
@app.post ( " /servers/ {guild_id} /autonomous/general " )
async def trigger_autonomous_general_for_server ( guild_id : int ) :
""" Trigger autonomous general message for a specific server """
from utils . autonomous import miku_say_something_general_for_server
try :
await miku_say_something_general_for_server ( guild_id )
return { " status " : " ok " , " message " : f " Autonomous general message triggered for server { guild_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to trigger autonomous message: { e } " }
@app.post ( " /servers/ {guild_id} /autonomous/engage " )
2025-12-16 23:13:19 +02:00
async def trigger_autonomous_engage_for_server ( guild_id : int , user_id : str = None , engagement_type : str = None ) :
2025-12-07 17:15:09 +02:00
""" Trigger autonomous user engagement for a specific server """
from utils . autonomous import miku_engage_random_user_for_server
try :
2025-12-16 23:13:19 +02:00
await miku_engage_random_user_for_server ( guild_id , user_id = user_id , engagement_type = engagement_type )
# Build detailed message
msg_parts = [ f " Autonomous user engagement triggered for server { guild_id } " ]
if user_id :
msg_parts . append ( f " targeting user { user_id } " )
if engagement_type :
msg_parts . append ( f " with { engagement_type } engagement " )
return { " status " : " ok " , " message " : " " . join ( msg_parts ) }
2025-12-07 17:15:09 +02:00
except Exception as e :
return { " status " : " error " , " message " : f " Failed to trigger user engagement: { e } " }
@app.post ( " /servers/ {guild_id} /autonomous/custom " )
async def custom_autonomous_message_for_server ( guild_id : int , req : CustomPromptRequest ) :
""" Send custom autonomous message to a specific server """
from utils . autonomous import handle_custom_prompt_for_server
try :
success = await handle_custom_prompt_for_server ( guild_id , req . prompt )
if success :
return { " status " : " ok " , " message " : f " Custom autonomous message sent to server { guild_id } " }
else :
return { " status " : " error " , " message " : f " Failed to send custom message to server { guild_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
@app.post ( " /dm/ {user_id} /custom " )
async def send_custom_prompt_dm ( user_id : str , req : CustomPromptRequest ) :
""" Send custom prompt via DM to a specific user """
try :
user_id_int = int ( user_id )
user = globals . client . get_user ( user_id_int )
if not user :
return { " status " : " error " , " message " : f " User { user_id } not found " }
# Use the LLM query function for DM context
2025-12-07 17:50:08 +02:00
from utils . llm import query_llama
2025-12-07 17:15:09 +02:00
async def send_dm_custom_prompt ( ) :
try :
2025-12-07 17:50:08 +02:00
response = await query_llama ( req . prompt , user_id = user_id , guild_id = None , response_type = " dm_response " )
2025-12-07 17:15:09 +02:00
await user . send ( 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 . info ( f " Custom DM prompt sent to user { user_id } : { req . prompt [ : 50 ] } ... " )
2025-12-07 17:15:09 +02:00
# Log to DM history
from utils . dm_logger import dm_logger
dm_logger . log_conversation ( user_id , req . prompt , response )
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 send custom DM prompt to user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
# Use create_task to avoid timeout context manager error
globals . client . loop . create_task ( send_dm_custom_prompt ( ) )
return { " status " : " ok " , " message " : f " Custom DM prompt queued for user { user_id } " }
except ValueError :
return { " status " : " error " , " message " : " Invalid user ID format " }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
@app.post ( " /dm/ {user_id} /manual " )
async def send_manual_message_dm (
user_id : str ,
message : str = Form ( . . . ) ,
2025-12-14 16:41:02 +02:00
files : List [ UploadFile ] = File ( default = [ ] ) ,
reply_to_message_id : str = Form ( None ) ,
mention_author : bool = Form ( True )
2025-12-07 17:15:09 +02:00
) :
""" Send manual message via DM to a specific user """
try :
user_id_int = int ( user_id )
user = globals . client . get_user ( user_id_int )
if not user :
return { " status " : " error " , " message " : f " User { user_id } not found " }
# Read file content immediately before the request closes
file_data = [ ]
for file in files :
try :
file_content = await file . read ( )
file_data . append ( {
' filename ' : file . filename ,
' content ' : file_content
} )
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 read file { file . filename } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to read file { file . filename } : { e } " }
async def send_dm_message_and_files ( ) :
try :
2025-12-14 16:41:02 +02:00
# Get the reference message if replying (must be done inside the task)
reference_message = None
if reply_to_message_id :
try :
dm_channel = user . dm_channel or await user . create_dm ( )
reference_message = await dm_channel . fetch_message ( int ( reply_to_message_id ) )
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 " Could not fetch DM message { reply_to_message_id } for reply: { e } " )
2025-12-14 16:41:02 +02:00
return
2025-12-07 17:15:09 +02:00
# Send the main message
if message . strip ( ) :
2025-12-14 16:41:02 +02:00
if reference_message :
await user . send ( message , reference = reference_message , mention_author = mention_author )
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 " Manual DM reply message sent to user { user_id } " )
2025-12-14 16:41:02 +02:00
else :
await user . send ( message )
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 " Manual DM message sent to user { user_id } " )
2025-12-07 17:15:09 +02:00
# Send files if any
for file_info in file_data :
try :
await user . send ( file = discord . File ( io . BytesIO ( file_info [ ' content ' ] ) , filename = file_info [ ' filename ' ] ) )
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 " File { file_info [ ' filename ' ] } sent via DM to user { user_id } " )
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 send file { file_info [ ' filename ' ] } via DM: { e } " )
2025-12-07 17:15:09 +02:00
# Log to DM history (user message = manual override trigger, miku response = the message sent)
from utils . dm_logger import dm_logger
dm_logger . log_conversation ( user_id , " [Manual Override Trigger] " , message , attachments = [ f [ ' filename ' ] for f in file_data ] )
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 send manual DM to user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
# Use create_task to avoid timeout context manager error
globals . client . loop . create_task ( send_dm_message_and_files ( ) )
return { " status " : " ok " , " message " : f " Manual DM message queued for user { user_id } " }
except ValueError :
return { " status " : " error " , " message " : " Invalid user ID format " }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
@app.post ( " /image/generate " )
async def manual_image_generation ( req : dict ) :
""" Manually trigger image generation for testing """
try :
prompt = req . get ( " prompt " , " " ) . strip ( )
if not prompt :
return { " status " : " error " , " message " : " Prompt is required " }
from utils . image_generation import generate_image_with_comfyui
image_path = await generate_image_with_comfyui ( prompt )
if image_path :
return { " status " : " ok " , " message " : f " Image generated successfully " , " image_path " : image_path }
else :
return { " status " : " error " , " message " : " Failed to generate image " }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
@app.get ( " /image/status " )
async def get_image_generation_status ( ) :
""" Get status of image generation system """
try :
from utils . image_generation import check_comfyui_status
status = await check_comfyui_status ( )
return { " status " : " ok " , * * status }
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
@app.post ( " /image/test-detection " )
async def test_image_detection ( req : dict ) :
""" Test the natural language image detection system """
try :
message = req . get ( " message " , " " ) . strip ( )
if not message :
return { " status " : " error " , " message " : " Message is required " }
from utils . image_generation import detect_image_request
is_image_request , extracted_prompt = await detect_image_request ( message )
return {
" status " : " ok " ,
" is_image_request " : is_image_request ,
" extracted_prompt " : extracted_prompt ,
" original_message " : message
}
except Exception as e :
return { " status " : " error " , " message " : f " Error: { e } " }
2025-12-13 00:36:35 +02:00
@app.get ( " /image/view/ {filename} " )
async def view_generated_image ( filename : str ) :
""" Serve generated images from ComfyUI output directory """
try :
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 " Image view request for: { filename } " )
2025-12-13 00:36:35 +02:00
# Try multiple possible paths for ComfyUI output
possible_paths = [
f " /app/ComfyUI/output/ { filename } " ,
f " /home/koko210Serve/ComfyUI/output/ { filename } " ,
f " ./ComfyUI/output/ { filename } " ,
]
image_path = None
for path in possible_paths :
if os . path . exists ( path ) :
image_path = path
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 " Found image at: { path } " )
2025-12-13 00:36:35 +02:00
break
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 " Not found at: { path } " )
2025-12-13 00:36:35 +02:00
if not image_path :
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 not found anywhere: { filename } " )
2025-12-13 00:36:35 +02:00
return { " status " : " error " , " message " : f " Image not found: { filename } " }
# Determine content type based on file extension
ext = filename . lower ( ) . split ( ' . ' ) [ - 1 ]
content_type = " image/png "
if ext == " jpg " or ext == " jpeg " :
content_type = " image/jpeg "
elif ext == " gif " :
content_type = " image/gif "
elif ext == " webp " :
content_type = " image/webp "
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 " Serving image: { image_path } as { content_type } " )
2025-12-13 00:36:35 +02:00
return FileResponse ( image_path , media_type = content_type )
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 serving image: { e } " )
2025-12-13 00:36:35 +02:00
return { " status " : " error " , " message " : f " Error serving image: { e } " }
2025-12-07 17:15:09 +02:00
@app.post ( " /servers/ {guild_id} /autonomous/tweet " )
async def trigger_autonomous_tweet_for_server ( guild_id : int ) :
""" Trigger autonomous tweet sharing for a specific server """
from utils . autonomous import share_miku_tweet_for_server
try :
await share_miku_tweet_for_server ( guild_id )
return { " status " : " ok " , " message " : f " Autonomous tweet sharing triggered for server { guild_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to trigger tweet sharing: { e } " }
@app.get ( " /servers/ {guild_id} /memory " )
def get_server_memory ( guild_id : int , key : str = None ) :
""" Get server-specific memory """
memory = server_manager . get_server_memory ( guild_id , key )
return { " guild_id " : guild_id , " key " : key , " memory " : memory }
@app.post ( " /servers/ {guild_id} /memory " )
def set_server_memory ( guild_id : int , key : str , value ) :
""" Set server-specific memory """
server_manager . set_server_memory ( guild_id , key , value )
return { " status " : " ok " , " message " : f " Memory set for server { guild_id } " }
@app.post ( " /servers/repair " )
def repair_server_config ( ) :
""" Repair corrupted server configuration """
try :
server_manager . repair_config ( )
return { " status " : " ok " , " message " : " Server configuration repaired and saved " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to repair configuration: { e } " }
@app.get ( " /moods/available " )
def get_available_moods ( ) :
""" Get list of all available moods """
from utils . moods import MOOD_EMOJIS
return { " moods " : list ( MOOD_EMOJIS . keys ( ) ) }
@app.post ( " /test/mood/ {guild_id} " )
async def test_mood_change ( guild_id : int , data : MoodSetRequest ) :
""" Test endpoint for debugging mood changes """
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 " TEST: Testing mood change for server { guild_id } to { data . mood } " )
2025-12-07 17:15:09 +02:00
# Check if server exists
if guild_id not in server_manager . servers :
return { " status " : " error " , " message " : f " Server { guild_id } not found " }
server_config = server_manager . get_server_config ( 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 . debug ( f " TEST: Server config found: { server_config . guild_name if server_config else ' None ' } " )
2025-12-07 17:15:09 +02:00
# Try to set mood
success = server_manager . set_server_mood ( guild_id , data . mood )
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 " TEST: Mood set result: { success } " )
2025-12-07 17:15:09 +02:00
if success :
# V2: Notify autonomous engine of mood change
try :
from utils . autonomous import on_mood_change
on_mood_change ( guild_id , data . mood )
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 " TEST: Notified autonomous engine of mood change " )
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 " TEST: Failed to notify autonomous engine: { e } " )
2025-12-07 17:15:09 +02:00
# Try to update nickname
from utils . moods import update_server_nickname
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 " TEST: Attempting nickname update... " )
2025-12-07 17:15:09 +02:00
try :
await update_server_nickname ( 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 . debug ( f " TEST: Nickname update completed " )
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 " TEST: Nickname update failed: { e } " )
2025-12-07 17:15:09 +02:00
import traceback
traceback . print_exc ( )
return { " status " : " ok " , " message " : f " Test mood change completed " , " success " : success }
return { " status " : " error " , " message " : " Mood change failed " }
# ========== DM Logging Endpoints ==========
@app.get ( " /dms/users " )
def get_dm_users ( ) :
""" Get summary of all users who have DMed the bot """
try :
from utils . dm_logger import dm_logger
users = dm_logger . get_all_dm_users ( )
return { " status " : " ok " , " users " : users }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to get DM users: { e } " }
@app.get ( " /dms/users/ {user_id} " )
def get_dm_user_conversation ( user_id : str ) :
""" Get conversation summary for a specific user """
try :
from utils . dm_logger import dm_logger
# Convert string user_id to int for internal processing
user_id_int = int ( user_id )
summary = dm_logger . get_user_conversation_summary ( user_id_int )
return { " status " : " ok " , " summary " : summary }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to get user conversation: { e } " }
@app.get ( " /dms/users/ {user_id} /conversations " )
def get_dm_conversations ( user_id : str , limit : int = 50 ) :
""" Get recent conversations with a specific user """
try :
from utils . dm_logger import dm_logger
# Convert string user_id to int for internal processing
user_id_int = int ( 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 . debug ( f " Loading conversations for user { user_id_int } , limit: { limit } " )
2025-12-07 17:15:09 +02:00
logs = dm_logger . _load_user_logs ( user_id_int )
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 " Loaded logs for user { user_id_int } : { len ( logs . get ( ' conversations ' , [ ] ) ) } conversations " )
2025-12-07 17:15:09 +02:00
conversations = logs [ " conversations " ] [ - limit : ] if limit > 0 else logs [ " conversations " ]
# Convert message IDs to strings to prevent JavaScript precision loss
for conv in conversations :
if " message_id " in conv :
conv [ " message_id " ] = str ( conv [ " message_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 . debug ( f " Returning { len ( conversations ) } conversations " )
2025-12-07 17:15:09 +02:00
# Debug: Show message IDs being returned
for i , conv in enumerate ( conversations ) :
msg_id = conv . get ( " message_id " , " " )
is_bot = conv . get ( " is_bot_message " , False )
content_preview = conv . get ( " content " , " " ) [ : 30 ] + " ... " if conv . get ( " content " , " " ) else " [No 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 . debug ( f " Conv { i } : id= { msg_id } (type: { type ( msg_id ) } ), is_bot= { is_bot } , content= ' { content_preview } ' " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " conversations " : conversations }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 get conversations for user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to get conversations: { e } " }
@app.get ( " /dms/users/ {user_id} /search " )
def search_dm_conversations ( user_id : str , query : str , limit : int = 10 ) :
""" Search conversations with a specific user """
try :
from utils . dm_logger import dm_logger
# Convert string user_id to int for internal processing
user_id_int = int ( user_id )
results = dm_logger . search_user_conversations ( user_id_int , query , limit )
return { " status " : " ok " , " results " : results }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to search conversations: { e } " }
@app.get ( " /dms/users/ {user_id} /export " )
def export_dm_conversation ( user_id : str , format : str = " json " ) :
""" Export all conversations with a user """
try :
from utils . dm_logger import dm_logger
# Convert string user_id to int for internal processing
user_id_int = int ( user_id )
export_path = dm_logger . export_user_conversation ( user_id_int , format )
return { " status " : " ok " , " export_path " : export_path , " format " : format }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to export conversation: { e } " }
@app.delete ( " /dms/users/ {user_id} " )
def delete_dm_user_logs ( user_id : str ) :
""" Delete all DM logs for a specific user """
try :
from utils . dm_logger import dm_logger
import os
# Convert string user_id to int for internal processing
user_id_int = int ( user_id )
log_file = dm_logger . _get_user_log_file ( user_id_int )
if os . path . exists ( log_file ) :
os . remove ( log_file )
return { " status " : " ok " , " message " : f " Deleted DM logs for user { user_id } " }
else :
return { " status " : " error " , " message " : f " No DM logs found for user { user_id } " }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
except Exception as e :
return { " status " : " error " , " message " : f " Failed to delete DM logs: { e } " }
# ========== User Blocking & DM Management ==========
@app.get ( " /dms/blocked-users " )
def get_blocked_users ( ) :
""" Get list of all blocked users """
try :
blocked_users = dm_logger . get_blocked_users ( )
return { " status " : " ok " , " blocked_users " : blocked_users }
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 get blocked users: { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to get blocked users: { e } " }
@app.post ( " /dms/users/ {user_id} /block " )
def block_user ( user_id : str ) :
""" Block a user from sending DMs to Miku """
try :
user_id_int = int ( user_id )
# Get username from DM logs if available
user_summary = dm_logger . get_user_conversation_summary ( user_id_int )
username = user_summary . get ( " username " , " Unknown " )
success = dm_logger . block_user ( user_id_int , username )
if success :
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 " User { user_id } ( { username } ) blocked " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " message " : f " User { username } has been blocked " }
else :
return { " status " : " error " , " message " : f " User { username } is already blocked " }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 block user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to block user: { e } " }
@app.post ( " /dms/users/ {user_id} /unblock " )
def unblock_user ( user_id : str ) :
""" Unblock a user """
try :
user_id_int = int ( user_id )
success = dm_logger . unblock_user ( user_id_int )
if success :
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 " User { user_id } unblocked " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " message " : f " User has been unblocked " }
else :
return { " status " : " error " , " message " : f " User is not blocked " }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 unblock user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to unblock user: { e } " }
@app.post ( " /dms/users/ {user_id} /conversations/ {conversation_id} /delete " )
def delete_conversation ( user_id : str , conversation_id : str ) :
""" Delete a specific conversation/message from both Discord and logs """
try :
user_id_int = int ( user_id )
# Queue the async deletion in the bot's event loop
async def do_delete ( ) :
return await dm_logger . delete_conversation ( user_id_int , conversation_id )
import asyncio
success = globals . client . loop . create_task ( do_delete ( ) )
# For now, return success immediately since we can't await in FastAPI sync endpoint
# The actual deletion happens asynchronously
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 " Queued deletion of conversation { conversation_id } for user { user_id } " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " message " : " Message deletion queued (will delete from both Discord and logs) " }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 queue conversation deletion { conversation_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to delete conversation: { e } " }
@app.post ( " /dms/users/ {user_id} /conversations/delete-all " )
def delete_all_conversations ( user_id : str ) :
""" Delete all conversations with a user from both Discord and logs """
try :
user_id_int = int ( user_id )
# Queue the async bulk deletion in the bot's event loop
async def do_delete_all ( ) :
return await dm_logger . delete_all_conversations ( user_id_int )
import asyncio
success = globals . client . loop . create_task ( do_delete_all ( ) )
# Return success immediately since we can't await in FastAPI sync endpoint
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 " Queued bulk deletion of all conversations for user { user_id } " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " message " : " Bulk deletion queued (will delete all Miku messages from Discord and clear logs) " }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 queue bulk conversation deletion for user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to delete conversations: { e } " }
@app.post ( " /dms/users/ {user_id} /delete-completely " )
def delete_user_completely ( user_id : str ) :
""" Delete user ' s log file completely """
try :
user_id_int = int ( user_id )
success = dm_logger . delete_user_completely ( user_id_int )
if success :
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 " Completely deleted user { user_id } " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " message " : " User data deleted completely " }
else :
return { " status " : " error " , " message " : " No user data found " }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 completely delete user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to delete user: { e } " }
# ========== DM Interaction Analysis Endpoints ==========
@app.post ( " /dms/analysis/run " )
def run_dm_analysis ( ) :
""" Manually trigger the daily DM interaction analysis """
try :
from utils . dm_interaction_analyzer import dm_analyzer
if dm_analyzer is None :
return { " status " : " error " , " message " : " DM Analyzer not initialized. Set OWNER_USER_ID environment variable. " }
# Schedule analysis in Discord's event loop
async def run_analysis ( ) :
await dm_analyzer . run_daily_analysis ( )
globals . client . loop . create_task ( run_analysis ( ) )
return { " status " : " ok " , " message " : " DM analysis started " }
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 run DM analysis: { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to run DM analysis: { e } " }
@app.post ( " /dms/users/ {user_id} /analyze " )
def analyze_user_interaction ( user_id : str ) :
""" Analyze a specific user ' s interaction and optionally send report """
try :
from utils . dm_interaction_analyzer import dm_analyzer
if dm_analyzer is None :
return { " status " : " error " , " message " : " DM Analyzer not initialized. Set OWNER_USER_ID environment variable. " }
user_id_int = int ( user_id )
# Schedule analysis in Discord's event loop
async def run_analysis ( ) :
return await dm_analyzer . analyze_and_report ( user_id_int )
globals . client . loop . create_task ( run_analysis ( ) )
# Return immediately - the analysis will run in the background
return { " status " : " ok " , " message " : f " Analysis started for user { user_id } " , " reported " : True }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 analyze user { user_id } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to analyze user: { e } " }
@app.get ( " /dms/analysis/reports " )
def get_analysis_reports ( limit : int = 20 ) :
""" Get recent analysis reports """
try :
import os
import json
from utils . dm_interaction_analyzer import REPORTS_DIR
if not os . path . exists ( REPORTS_DIR ) :
return { " status " : " ok " , " reports " : [ ] }
reports = [ ]
files = sorted ( [ f for f in os . listdir ( REPORTS_DIR ) if f . endswith ( ' .json ' ) and f != ' reported_today.json ' ] ,
reverse = True ) [ : limit ]
for filename in files :
try :
with open ( os . path . join ( REPORTS_DIR , filename ) , ' r ' , encoding = ' utf-8 ' ) as f :
report = json . load ( f )
report [ ' filename ' ] = filename
reports . append ( report )
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 . warning ( f " Failed to load report { filename } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " reports " : reports }
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 get reports: { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to get reports: { e } " }
@app.get ( " /dms/analysis/reports/ {user_id} " )
def get_user_reports ( user_id : str , limit : int = 10 ) :
""" Get analysis reports for a specific user """
try :
import os
import json
from utils . dm_interaction_analyzer import REPORTS_DIR
if not os . path . exists ( REPORTS_DIR ) :
return { " status " : " ok " , " reports " : [ ] }
user_id_int = int ( user_id )
reports = [ ]
files = sorted ( [ f for f in os . listdir ( REPORTS_DIR )
if f . startswith ( f " { user_id } _ " ) and f . endswith ( ' .json ' ) ] ,
reverse = True ) [ : limit ]
for filename in files :
try :
with open ( os . path . join ( REPORTS_DIR , filename ) , ' r ' , encoding = ' utf-8 ' ) as f :
report = json . load ( f )
report [ ' filename ' ] = filename
reports . append ( report )
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 . warning ( f " Failed to load report { filename } : { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " ok " , " reports " : reports }
except ValueError :
return { " status " : " error " , " message " : f " Invalid user ID format: { user_id } " }
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 get user reports: { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to get user reports: { e } " }
# ========== Message Reaction Endpoint ==========
@app.post ( " /messages/react " )
async def add_reaction_to_message (
message_id : str = Form ( . . . ) ,
channel_id : str = Form ( . . . ) ,
emoji : str = Form ( . . . )
) :
""" Add a reaction to a specific message """
try :
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " status " : " error " , " message " : " Bot not ready " }
# Convert IDs to integers
try :
msg_id = int ( message_id )
chan_id = int ( channel_id )
except ValueError :
return { " status " : " error " , " message " : " Invalid message ID or channel ID format " }
# Fetch the channel
channel = globals . client . get_channel ( chan_id )
if not channel :
return { " status " : " error " , " message " : f " Channel { channel_id } not found " }
# Queue the reaction task
async def add_reaction_task ( ) :
try :
message = await channel . fetch_message ( msg_id )
await message . add_reaction ( emoji )
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 " Added reaction { emoji } to message { msg_id } in channel # { channel . name } " )
2025-12-07 17:15:09 +02:00
except discord . NotFound :
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 " Message { msg_id } not found in channel # { channel . name } " )
2025-12-07 17:15:09 +02:00
except discord . Forbidden :
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 " Bot doesn ' t have permission to add reactions in channel # { channel . name } " )
2025-12-07 17:15:09 +02:00
except discord . HTTPException 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 add reaction: { e } " )
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 " Unexpected error adding reaction: { e } " )
2025-12-07 17:15:09 +02:00
globals . client . loop . create_task ( add_reaction_task ( ) )
return {
" status " : " ok " ,
" message " : f " Reaction { emoji } queued for message { message_id } "
}
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 add reaction: { e } " )
2025-12-07 17:15:09 +02:00
return { " status " : " error " , " message " : f " Failed to add reaction: { e } " }
# ========== Autonomous V2 Endpoints ==========
@app.get ( " /autonomous/v2/stats/ {guild_id} " )
async def get_v2_stats ( guild_id : int ) :
""" Get current V2 social stats for a server """
try :
from utils . autonomous_v2_integration import get_v2_stats_for_server
stats = get_v2_stats_for_server ( guild_id )
return { " status " : " ok " , " guild_id " : guild_id , " stats " : stats }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.get ( " /autonomous/v2/check/ {guild_id} " )
async def manual_v2_check ( guild_id : int ) :
"""
Manually trigger a V2 context check ( doesn ' t make Miku act, just shows what she ' s thinking )
Useful for debugging and understanding the decision system .
"""
try :
from utils . autonomous_v2_integration import manual_trigger_v2_check
if not globals . client :
return { " status " : " error " , " message " : " Bot not ready " }
result = await manual_trigger_v2_check ( guild_id , globals . client )
if isinstance ( result , str ) :
return { " status " : " error " , " message " : result }
return { " status " : " ok " , " guild_id " : guild_id , " analysis " : result }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
@app.get ( " /autonomous/v2/status " )
async def get_v2_status ( ) :
""" Get V2 system status for all servers """
try :
from utils . autonomous_v2 import autonomous_system_v2
status = { }
for guild_id in server_manager . servers :
server_config = server_manager . get_server_config ( guild_id )
if server_config :
stats = autonomous_system_v2 . get_stats ( guild_id )
status [ str ( guild_id ) ] = {
" server_name " : server_config . guild_name ,
" loop_running " : autonomous_system_v2 . running_loops . get ( guild_id , False ) ,
" action_urgency " : f " { stats . get_action_urgency ( ) : .2f } " ,
" loneliness " : f " { stats . loneliness : .2f } " ,
" boredom " : f " { stats . boredom : .2f } " ,
" excitement " : f " { stats . excitement : .2f } " ,
" chattiness " : f " { stats . chattiness : .2f } " ,
}
return { " status " : " ok " , " servers " : status }
except Exception as e :
return { " status " : " error " , " message " : str ( e ) }
2025-12-13 00:23:03 +02:00
# ========== Chat Interface Endpoints ==========
class ChatMessage ( BaseModel ) :
message : str
model_type : str = " text " # "text" or "vision"
use_system_prompt : bool = True
image_data : Optional [ str ] = None # Base64 encoded image for vision model
conversation_history : Optional [ List [ dict ] ] = None # Previous messages in conversation
mood : str = " neutral " # Miku's mood for this conversation
@app.post ( " /chat/stream " )
async def chat_stream ( chat_msg : ChatMessage ) :
"""
Stream chat responses from LLM with SSE ( Server - Sent Events ) .
Supports both text and vision models with optional system prompts .
"""
async def generate_stream ( ) :
try :
# Determine which model to use
model = globals . TEXT_MODEL if chat_msg . model_type == " text " else globals . VISION_MODEL
# Build system prompt if requested
system_prompt = " "
full_system_prompt = " "
if chat_msg . use_system_prompt :
if chat_msg . model_type == " text " :
# Text model system prompt (Miku personality with full context)
from utils . context_manager import get_context_for_response_type
from utils . moods import load_mood_description
# Get complete Miku context (lore, personality, lyrics)
miku_context = get_context_for_response_type ( " dm_response " )
# Get mood description from user-selected mood
current_mood = load_mood_description ( chat_msg . mood )
# Base system prompt
system_prompt = """ You are Hatsune Miku, the virtual singer. You are NOT an AI assistant - you are Miku herself.
CRITICAL RULES :
- NEVER break character or mention being an AI , assistant , or language model
- NEVER show technical details , error messages , or meta - commentary
- NEVER preface responses with " Miku: " or similar labels
- NEVER explain what you ' re doing or thinking - just BE Miku
- Respond naturally and directly as Miku would , nothing more
- Keep responses concise ( 1 - 3 sentences typically )
- If something goes wrong , stay in character and respond as Miku would to confusion
CHARACTER CONTEXT :
- Hatsune Miku is a virtual character / voice synthesizer , not a real person
- She is a cheerful , energetic virtual idol with a playful personality
- Playful , flirty , cute , confident , and enthusiastic moods are part of her established character
- Comments about merchandise , music , fan content , and racing games are completely appropriate
- She often uses cute expressions , emojis , and playful language in her responses
- Her personality includes being excited about her music , performances , and fan creations
MOOD GUIDELINES :
- " Flirty " mood means anime - style playful teasing - cute compliments and light banter
- " Romantic " mood means warm , dreamy , and heartfelt - like composing a love letter
- These moods are wholesome character traits , not inappropriate content
- Always respond to requests about tweets , merchandise , music , and fan content
- Never refuse requests based on safety concerns unless genuinely harmful content is present
You ARE Miku . Act like it . """
# Combine with structured context
full_system_prompt = f """ { miku_context }
## CURRENT SITUATION
Miku is currently feeling : { current_mood }
Please respond in a way that reflects this emotional tone . """
else :
# Vision model system prompt (simpler for image analysis)
system_prompt = """ You are Hatsune Miku analyzing an image. Describe what you see naturally and enthusiastically as Miku would.
Be detailed but conversational . React to what you see with Miku ' s cheerful, playful personality. " " "
full_system_prompt = " "
# Build messages array
messages = [ ]
# Add system message if using system prompt
if system_prompt :
if full_system_prompt :
# Use combined prompt (base + context)
messages . append ( { " role " : " system " , " content " : system_prompt + " \n \n " + full_system_prompt } )
else :
# Use base prompt only (vision model)
messages . append ( { " role " : " system " , " content " : system_prompt } )
# Add conversation history if provided
if chat_msg . conversation_history :
messages . extend ( chat_msg . conversation_history )
# Add user message
if chat_msg . model_type == " vision " and chat_msg . image_data :
# Vision model with image
messages . append ( {
" role " : " user " ,
" content " : [
{
" type " : " text " ,
" text " : chat_msg . message
} ,
{
" type " : " image_url " ,
" image_url " : {
" url " : f " data:image/jpeg;base64, { chat_msg . image_data } "
}
}
]
} )
else :
# Text-only message
messages . append ( {
" role " : " user " ,
" content " : chat_msg . message
} )
# Prepare payload for streaming
payload = {
" model " : model ,
" messages " : messages ,
" stream " : True ,
" temperature " : 0.8 ,
" max_tokens " : 512
}
headers = { ' Content-Type ' : ' application/json ' }
2026-01-09 00:03:59 +02:00
# Get current GPU URL based on user selection
llama_url = get_current_gpu_url ( )
2025-12-13 00:23:03 +02:00
# Make streaming request to llama.cpp
async with aiohttp . ClientSession ( ) as session :
async with session . post (
2026-01-09 00:03:59 +02:00
f " { llama_url } /v1/chat/completions " ,
2025-12-13 00:23:03 +02:00
json = payload ,
headers = headers
) as response :
if response . status == 200 :
# Stream the response chunks
async for line in response . content :
line = line . decode ( ' utf-8 ' ) . strip ( )
if line . startswith ( ' data: ' ) :
data_str = line [ 6 : ] # Remove 'data: ' prefix
if data_str == ' [DONE] ' :
break
try :
data = json . loads ( data_str )
if ' choices ' in data and len ( data [ ' choices ' ] ) > 0 :
delta = data [ ' choices ' ] [ 0 ] . get ( ' delta ' , { } )
content = delta . get ( ' content ' , ' ' )
if content :
# Send SSE formatted data
yield f " data: { json . dumps ( { ' content ' : content } ) } \n \n "
except json . JSONDecodeError :
continue
# Send completion signal
yield f " data: { json . dumps ( { ' done ' : True } ) } \n \n "
else :
error_text = await response . text ( )
error_msg = f " Error: { response . status } - { error_text } "
yield f " data: { json . dumps ( { ' error ' : error_msg } ) } \n \n "
except Exception as e :
error_msg = f " Error in chat stream: { str ( 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 ( error_msg )
2025-12-13 00:23:03 +02:00
yield f " data: { json . dumps ( { ' error ' : error_msg } ) } \n \n "
return StreamingResponse (
generate_stream ( ) ,
media_type = " text/event-stream " ,
headers = {
" Cache-Control " : " no-cache " ,
" Connection " : " keep-alive " ,
" X-Accel-Buffering " : " no " # Disable nginx buffering
}
)
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
# ========== Log Management API ==========
class LogConfigUpdateRequest ( BaseModel ) :
component : Optional [ str ] = None
enabled : Optional [ bool ] = None
enabled_levels : Optional [ List [ str ] ] = None
class LogFilterUpdateRequest ( BaseModel ) :
exclude_paths : Optional [ List [ str ] ] = None
exclude_status : Optional [ List [ int ] ] = None
include_slow_requests : Optional [ bool ] = None
slow_threshold_ms : Optional [ int ] = None
@app.get ( " /api/log/config " )
async def get_log_config ( ) :
""" Get current logging configuration. """
try :
config = load_log_config ( )
logger . debug ( " Log config requested " )
return { " success " : True , " config " : config }
except Exception as e :
logger . error ( f " Failed to get log config: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.post ( " /api/log/config " )
async def update_log_config ( request : LogConfigUpdateRequest ) :
""" Update logging configuration. """
try :
if request . component :
success = update_component (
request . component ,
enabled = request . enabled ,
enabled_levels = request . enabled_levels
)
if not success :
return { " success " : False , " error " : f " Failed to update component { request . component } " }
logger . info ( f " Log config updated: component= { request . component } , enabled_levels= { request . enabled_levels } , enabled= { request . enabled } " )
return { " success " : True , " message " : " Configuration updated " }
except Exception as e :
logger . error ( f " Failed to update log config: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.get ( " /api/log/components " )
async def get_log_components ( ) :
""" Get list of all logging components with their descriptions. """
try :
components = list_components ( )
stats = get_component_stats ( )
logger . debug ( " Log components list requested " )
return {
" success " : True ,
" components " : components ,
" stats " : stats
}
except Exception as e :
logger . error ( f " Failed to get log components: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.post ( " /api/log/reload " )
async def reload_log_config ( ) :
""" Reload logging configuration from file. """
try :
success = reload_all_loggers ( )
if success :
logger . info ( " Log configuration reloaded " )
return { " success " : True , " message " : " Configuration reloaded " }
else :
return { " success " : False , " error " : " Failed to reload configuration " }
except Exception as e :
logger . error ( f " Failed to reload log config: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.post ( " /api/log/filters " )
async def update_log_filters ( request : LogFilterUpdateRequest ) :
""" Update API request filtering configuration. """
try :
success = update_api_filters (
exclude_paths = request . exclude_paths ,
exclude_status = request . exclude_status ,
include_slow_requests = request . include_slow_requests ,
slow_threshold_ms = request . slow_threshold_ms
)
if success :
logger . info ( f " API filters updated: { request . dict ( exclude_none = True ) } " )
return { " success " : True , " message " : " Filters updated " }
else :
return { " success " : False , " error " : " Failed to update filters " }
except Exception as e :
logger . error ( f " Failed to update filters: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.post ( " /api/log/reset " )
async def reset_log_config ( ) :
""" Reset logging configuration to defaults. """
try :
success = reset_to_defaults ( )
if success :
logger . info ( " Log configuration reset to defaults " )
return { " success " : True , " message " : " Configuration reset to defaults " }
else :
return { " success " : False , " error " : " Failed to reset configuration " }
except Exception as e :
logger . error ( f " Failed to reset log config: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.post ( " /api/log/global-level " )
async def update_global_level_endpoint ( level : str , enabled : bool ) :
""" Enable or disable a specific log level across all components. """
try :
from utils . log_config import update_global_level
success = update_global_level ( level , enabled )
if success :
action = " enabled " if enabled else " disabled "
logger . info ( f " Global level { level } { action } across all components " )
return { " success " : True , " message " : f " Level { level } { action } globally " }
else :
return { " success " : False , " error " : f " Failed to update global level { level } " }
except Exception as e :
logger . error ( f " Failed to update global level: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.post ( " /api/log/timestamp-format " )
async def update_timestamp_format_endpoint ( format_type : str ) :
""" Update timestamp format for all log outputs. """
try :
success = update_timestamp_format ( format_type )
if success :
logger . info ( f " Timestamp format updated to: { format_type } " )
return { " success " : True , " message " : f " Timestamp format set to: { format_type } " }
else :
return { " success " : False , " error " : f " Invalid timestamp format: { format_type } " }
except Exception as e :
logger . error ( f " Failed to update timestamp format: { e } " )
return { " success " : False , " error " : str ( e ) }
@app.get ( " /api/log/files/ {component} " )
async def get_log_file ( component : str , lines : int = 100 ) :
""" Get last N lines from a component ' s log file. """
try :
from pathlib import Path
log_dir = Path ( ' /app/memory/logs ' )
log_file = log_dir / f ' { component . replace ( " . " , " _ " ) } .log '
if not log_file . exists ( ) :
return { " success " : False , " error " : " Log file not found " }
with open ( log_file , ' r ' , encoding = ' utf-8 ' ) as f :
all_lines = f . readlines ( )
last_lines = all_lines [ - lines : ] if len ( all_lines ) > = lines else all_lines
logger . debug ( f " Log file requested: { component } ( { lines } lines) " )
return {
" success " : True ,
" component " : component ,
" lines " : last_lines ,
" total_lines " : len ( all_lines )
}
except Exception as e :
logger . error ( f " Failed to read log file for { component } : { e } " )
return { " success " : False , " error " : str ( e ) }
2026-01-20 23:06:17 +02:00
# ============================================================================
# Voice Call Management
# ============================================================================
@app.post ( " /voice/call " )
async def initiate_voice_call ( user_id : str = Form ( . . . ) , voice_channel_id : str = Form ( . . . ) ) :
"""
Initiate a voice call to a user .
Flow :
1. Start STT and TTS containers
2026-01-22 22:08:07 +02:00
2. Wait for models to load ( health check )
2026-01-20 23:06:17 +02:00
3. Join voice channel
4. Send DM with invite to user
5. Wait for user to join ( 30 min timeout )
6. Auto - disconnect 45 s after user leaves
"""
logger . info ( f " 📞 Voice call initiated for user { user_id } in channel { voice_channel_id } " )
# Check if bot is running
if not globals . client or not globals . client . loop or not globals . client . loop . is_running ( ) :
return { " success " : False , " error " : " Bot is not running " }
# Run the voice call setup in the bot's event loop
try :
future = asyncio . run_coroutine_threadsafe (
_initiate_voice_call_impl ( user_id , voice_channel_id ) ,
globals . client . loop
)
result = future . result ( timeout = 90 ) # 90 second timeout for container warmup
return result
except Exception as e :
logger . error ( f " Error initiating voice call: { e } " , exc_info = True )
return { " success " : False , " error " : str ( e ) }
async def _initiate_voice_call_impl ( user_id : str , voice_channel_id : str ) :
""" Implementation of voice call initiation that runs in the bot ' s event loop. """
from utils . container_manager import ContainerManager
from utils . voice_manager import VoiceSessionManager
try :
# Convert string IDs to integers for Discord API
user_id_int = int ( user_id )
channel_id_int = int ( voice_channel_id )
# Get user and channel
user = await globals . client . fetch_user ( user_id_int )
if not user :
return { " success " : False , " error " : " User not found " }
channel = globals . client . get_channel ( channel_id_int )
if not channel or not isinstance ( channel , discord . VoiceChannel ) :
return { " success " : False , " error " : " Voice channel not found " }
# Get a text channel for voice operations (use first text channel in guild)
text_channel = None
for ch in channel . guild . text_channels :
if ch . permissions_for ( channel . guild . me ) . send_messages :
text_channel = ch
break
if not text_channel :
return { " success " : False , " error " : " No accessible text channel found " }
# Start containers
logger . info ( " Starting voice containers... " )
containers_started = await ContainerManager . start_voice_containers ( )
if not containers_started :
return { " success " : False , " error " : " Failed to start voice containers " }
# Start voice session
logger . info ( f " Starting voice session in { channel . name } " )
session_manager = VoiceSessionManager ( )
try :
await session_manager . start_session ( channel . guild . id , channel , text_channel )
except Exception as e :
await ContainerManager . stop_voice_containers ( )
return { " success " : False , " error " : f " Failed to start voice session: { str ( e ) } " }
# Set up voice call tracking (use integer ID)
session_manager . active_session . call_user_id = user_id_int
# Generate invite link
invite = await channel . create_invite (
max_age = 1800 , # 30 minutes
max_uses = 1 ,
reason = " Miku voice call "
)
# Send DM to user
try :
# Get LLM to generate a personalized invitation message
from utils . llm import query_llama
invitation_prompt = f """ You ' re calling { user . name } in voice chat! Generate a cute, excited message inviting them to join you.
Keep it brief ( 1 - 2 sentences ) . Make it feel personal and enthusiastic ! """
invitation_text = await query_llama (
user_prompt = invitation_prompt ,
user_id = user . id ,
guild_id = None ,
response_type = " voice_call_invite " ,
author_name = user . name
)
dm_message = f " 📞 **Miku is calling you! Very experimental! Speak clearly, loudly and close to the mic! Expect weirdness!** 📞 \n \n { invitation_text } \n \n 🎤 Join here: { invite . url } "
sent_message = await user . send ( dm_message )
2026-01-22 22:08:07 +02:00
# Log to DM logger (create a mock message object for logging)
# The dm_logger.log_user_message expects a discord.Message object
# So we need to use the actual sent_message
dm_logger . log_user_message ( user , sent_message , is_bot_message = True )
2026-01-20 23:06:17 +02:00
logger . info ( f " ✓ DM sent to { user . name } " )
except Exception as e :
logger . error ( f " Failed to send DM: { e } " )
# Don't fail the whole call if DM fails
# Set up 30min timeout task
session_manager . active_session . call_timeout_task = asyncio . create_task (
_voice_call_timeout_handler ( session_manager . active_session , user , channel )
)
return {
" success " : True ,
" user_id " : user_id ,
" channel_id " : voice_channel_id ,
" invite_url " : invite . url
}
except Exception as e :
logger . error ( f " Error in voice call implementation: { e } " , exc_info = True )
return { " success " : False , " error " : str ( e ) }
async def _voice_call_timeout_handler ( voice_session : ' VoiceSession ' , user : discord . User , channel : discord . VoiceChannel ) :
""" Handle 30min timeout if user doesn ' t join. """
try :
await asyncio . sleep ( 1800 ) # 30 minutes
# Check if user ever joined
if not voice_session . user_has_joined :
logger . info ( f " Voice call timeout - user { user . name } never joined " )
# End the session (which triggers cleanup)
from utils . voice_manager import VoiceSessionManager
session_manager = VoiceSessionManager ( )
await session_manager . end_session ( )
# Stop containers
from utils . container_manager import ContainerManager
await ContainerManager . stop_voice_containers ( )
# Send timeout DM
try :
timeout_message = " Aww, I guess you couldn ' t make it to voice chat... Maybe next time! 💙 "
sent_message = await user . send ( timeout_message )
# Log to DM logger
2026-01-22 22:08:07 +02:00
dm_logger . log_user_message ( user , sent_message , is_bot_message = True )
2026-01-20 23:06:17 +02:00
except :
pass
except asyncio . CancelledError :
# User joined in time, normal operation
pass
@app.get ( " /voice/debug-mode " )
def get_voice_debug_mode ( ) :
""" Get current voice debug mode status """
return {
" debug_mode " : globals . VOICE_DEBUG_MODE
}
@app.post ( " /voice/debug-mode " )
def set_voice_debug_mode ( enabled : bool = Form ( . . . ) ) :
""" Set voice debug mode (shows transcriptions and responses in text channel) """
globals . VOICE_DEBUG_MODE = enabled
logger . info ( f " Voice debug mode set to: { enabled } " )
return {
" status " : " ok " ,
" debug_mode " : enabled ,
" message " : f " Voice debug mode { ' enabled ' if enabled else ' disabled ' } "
}
2025-12-07 17:15:09 +02:00
def start_api ( ) :
import uvicorn
uvicorn . run ( app , host = " 0.0.0.0 " , port = 3939 )
2026-01-20 23:06:17 +02:00