#16 Timezone consistency — added TZ=Europe/Sofia to docker-compose.yml
so datetime.now() returns local time inside the container. Removed
the +3 hour hack from get_time_of_day(). All three time-of-day
consumers (autonomous_v1_legacy, moods, autonomous_engine) now
use the same correct local hour automatically.
#17 Decay truncation — replaced int() with round() in decay_events()
so a counter of 1 survives one more 15-minute cycle instead of
being immediately zeroed (round(0.841)=1 vs int(0.841)=0).
#20 Unpersisted rate limiter — _last_action_execution dict in
autonomous.py is now seeded from the engine's persisted
server_last_action on import, so restarts don't bypass the
30-second cooldown.
Note: #18 (dead config fields) was a false positive — autonomous_interval_minutes
IS used by the scheduler. #19 deferred to bipolar mode rework.
#10 Redundant coin flip in join_conversation — removed the 50% random
gate that doubled the V2 engine's own decision to act.
#11 Message-triggered actions skip _autonomous_paused — _check_and_act
and _check_and_react now bail out immediately when the autonomous
system is paused (voice session), matching the scheduled-tick path.
#12 Duplicate emoji dictionaries — removed MOOD_EMOJIS and
EVIL_MOOD_EMOJIS from globals.py (had different emojis from moods.py).
bipolar_mode.py and evil_mode.py now import the canonical dicts
from utils/moods.py so all code sees the same emojis.
#13 DM mood can spontaneously become 'asleep' — rotate_dm_mood() now
filters 'asleep' out of the candidate list since DMs have no
sleepy-to-asleep transition guard and no wakeup timer.
#15 Engage-user fallback misreports action type — log level raised to
WARNING with an explicit [engage_user->general] prefix so the
cooldown-triggered fallback is visible in logs.
- Added manual_trigger parameter to /autonomous/engage endpoint to bypass 12h cooldown
- Updated miku_engage_random_user_for_server() and miku_engage_random_user() to accept manual_trigger flag
- Modified Web UI to always send manual_trigger=true when engaging users from the UI
- Users can now manually engage the same user multiple times from web UI without cooldown restriction
- Regular autonomous schedules still respect the 12h cooldown between engagements to the same user
Changes:
- bot/api.py: Added manual_trigger parameter with string-to-boolean conversion
- bot/static/index.html: Added manual_trigger=true to engage user request
- bot/utils/autonomous_v1_legacy.py: Added manual_trigger parameter and cooldown bypass logic
- 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.
- Added Evil Miku mode with 4 evil moods (aggressive, cunning, sarcastic, evil_neutral)
- Created evil mode content files (evil_miku_lore.txt, evil_miku_prompt.txt, evil_miku_lyrics.txt)
- Implemented persistent evil mode state across restarts (saves to memory/evil_mode_state.json)
- Fixed API endpoints to use client.loop.create_task() to prevent timeout errors
- Added evil mode toggle in web UI with red theme styling
- Modified mood rotation to handle evil mode
- Configured DarkIdol uncensored model for evil mode text generation
- Reduced system prompt redundancy by removing duplicate content
- Added markdown escape for single asterisks (actions) while preserving bold formatting
- Evil mode now persists username, pfp, and nicknames across restarts without re-applying changes
- Replace simple 'Engage Random User' button with expandable submenu
- Add user ID input field for targeting specific users
- Add engagement type selection: random, activity-based, general, status-based
- Update API endpoints to accept user_id and engagement_type parameters
- Modify autonomous functions to support targeted engagement
- Maintain backward compatibility with random user/type selection as default
- Added /autonomous/join-conversation API endpoint in api.py
- Added 'Detect and Join Conversation' button to Web UI under Autonomous Actions
- Added 'autonomous join-conversation' command to CLI tool (miku-cli.py)
- Updated miku_detect_and_join_conversation_for_server to support force=True parameter
- When force=True: skips time limit, activity checks, and random chance
- Force mode uses last 10 user messages regardless of age
- Manual triggers via Web UI/CLI now work even with old messages