122 Commits

Author SHA1 Message Date
54d9a80089 fixed webhook pfp for regular miku being wrong when evil mode active 2026-03-05 22:16:14 +02:00
832fc0d039 added test log with multiple various test scenarios between models and evil/regular miku 2026-03-05 22:04:26 +02:00
d5b9964ce7 Fix vision pipeline: route images through Cat, pass user question to vision model
- Fix silent None return in analyze_image_with_vision exception handler
- Add None/empty guards after vision analysis in bot.py (image, video, GIF, Tenor)
- Route all image/video/GIF responses through Cheshire Cat pipeline (was
  calling query_llama directly), enabling episodic memory storage for media
  interactions and correct Last Prompt display in Web UI
- Add media_type parameter to cat_adapter.query() and forward as
  discord_media_type in WebSocket payload
- Update discord_bridge plugin to read media_type from payload and inject
  MEDIA NOTE into system prefix in before_agent_starts hook
- Add _extract_vision_question() helper to strip Discord mentions and bot-name
  triggers from user message; pass cleaned question to vision model so specific
  questions (e.g. 'what is the person wearing?') go directly to the vision model
  instead of the generic 'Describe this image in detail.' fallback
- Pass user_prompt to all analyze_image_with_qwen / analyze_video_with_vision
  call sites in bot.py (image, video, GIF, Tenor, embed paths)
- Fix autonomous reaction loops skipping messages that @mention the bot or have
  media attachments in DMs, preventing duplicate vision model calls for images
  already being processed by the main message handler
- Increase vision max_tokens: images 300->800, video/GIF 400->1000 (no VRAM
  impact; KV cache is pre-allocated at model load time)
2026-03-05 21:59:27 +02:00
ae1e0aa144 add: cheshire-cat configuration, tooling, tests, and documentation
Configuration:
- .env.example, .gitignore, compose.yml (main docker compose)
- docker-compose-amd.yml (ROCm), docker-compose-macos.yml
- start.sh, stop.sh convenience scripts
- LICENSE (Apache 2.0, from upstream Cheshire Cat)

Memory management utilities:
- analyze_consolidation.py, manual_consolidation.py, verify_consolidation.py
- check_memories.py, extract_declarative_facts.py, store_declarative_facts.py
- compare_systems.py (system comparison tool)
- benchmark_cat.py, streaming_benchmark.py, streaming_benchmark_v2.py

Test suite:
- quick_test.py, test_setup.py, test_setup_simple.py
- test_consolidation_direct.py, test_declarative_recall.py, test_recall.py
- test_end_to_end.py, test_full_pipeline.py
- test_phase2.py, test_phase2_comprehensive.py

Documentation:
- README.md, QUICK_START.txt, TEST_README.md, SETUP_COMPLETE.md
- PHASE2_IMPLEMENTATION_NOTES.md, PHASE2_TEST_RESULTS.md
- POST_OPTIMIZATION_ANALYSIS.md
2026-03-04 00:51:14 +02:00
eafab336b4 feat: add Traefik proxy, custom chat template, improve Cheshire Cat memory
docker-compose.yml:
- Add Traefik proxy network + labels for miku.panel domain
- Connect miku-bot service to proxy network

llama-swap-config.yaml / llama-swap-rocm-config.yaml:
- Add --chat-template-file flag to disable Llama 3.1 built-in tool
  calling (was causing malformed responses)
- ROCm config: add Rocinante-X 12B model entry for comparison testing

cheshire-cat discord_bridge plugin:
- Increase declarative memory recall (k=3→10, threshold 0.7→0.5)
  for better factual retrieval
- Add agent_prompt_prefix hook to enforce factual accuracy from
  declarative memories
- Add before_agent_starts debug logging for memory inspection
- Add passthrough hooks for message/suffix pipeline
2026-03-04 00:48:58 +02:00
335b58a867 feat: fix evil mode race conditions, expand moods and PFP detection
bipolar_mode.py:
- Replace unsafe globals.EVIL_MODE temporary overrides with
  force_evil_context parameter to fix async race conditions (3 sites)

moods.py:
- Add 6 new evil mood emojis: bored, manic, jealous, melancholic,
  playful_cruel, contemptuous
- Refactor rotate_dm_mood() to skip when evil mode active (evil mode
  has its own independent 2-hour rotation timer)

persona_dialogue.py:
- Same force_evil_context race condition fix (2 sites)
- Fix over-aggressive response cleanup that stripped common words
  (YES/NO/HIGH) — now uses targeted regex for structural markers only
- Update evil mood multipliers to match new mood set

profile_picture_context:
- Expand PFP detection regex for broader coverage (appearance questions,
  opinion queries, selection/change questions)
- Add plugin.json metadata file
2026-03-04 00:45:23 +02:00
5898b0eb3b fix: update .gitignore to cover all bot/memory subdirs, untrack runtime data
- Change bot/memory/*.json to bot/memory/** to properly ignore all
  subdirectories (dms/, dm_reports/, profile_pictures/)
- Untrack bot/memory/ files from index (DMs, profile pics, dm reports)
- Untrack cheshire-cat discord_bridge __pycache__/*.pyc from index
- These files are runtime/user data that should never be in version control
2026-03-04 00:43:10 +02:00
8ca716029e add: absorb soprano_to_rvc as regular subdirectory
Voice conversion pipeline (Soprano TTS → RVC) with Docker support.
Previously tracked as bare gitlink; removed .git/ directories and
absorbed into main repo for unified tracking.

Includes: Soprano TTS, RVC WebUI integration, Docker configs,
WebSocket API, and benchmark scripts.
Updated .gitignore to exclude large model weights (*.pth, *.pt, *.onnx, *.index).
287 files (3.1GB of ML weights properly excluded via gitignore).
2026-03-04 00:24:53 +02:00
34b184a05a add: absorb uno-online as regular subdirectory
UNO card game web app (Node.js/React) with Miku bot integration.
Previously an independent git repo (fork of mizanxali/uno-online).
Removed .git/ and absorbed into main repo for unified tracking.

Includes bot integration code: botActionExecutor, cardParser,
gameStateBuilder, and server-side bot action support.
37 files, node_modules excluded via local .gitignore.
2026-03-04 00:21:38 +02:00
c708770266 reorganize: consolidate all documentation into readmes/
- Moved 20 root-level markdown files to readmes/
- Includes COMMANDS.md, CONFIG_README.md, all UNO docs, all completion reports
- Added new: MEMORY_EDITOR_FEATURE.md, MEMORY_EDITOR_ESCAPING_FIX.md,
  CONFIG_SOURCES_ANALYSIS.md, MCP_TOOL_CALLING_ANALYSIS.md, and others
- Root directory is now clean of documentation clutter
2026-03-04 00:19:49 +02:00
fdde12c03d reorganize: move all test scripts to tests/ directory
- Moved 8 root-level test scripts + 2 from bot/ to tests/
- Moved run_rocinante_test.sh runner script to tests/
- Added tests/README.md documenting each test's purpose, type, and requirements
- Added test_pfp_context.py and test_rocinante_comparison.py (previously untracked)
2026-03-04 00:18:21 +02:00
431f675fc7 cleanup: update .gitignore, sanitize .env.example, remove stale files
- Expanded .gitignore: miku-app/, dashboard/, .continue/, *.code-workspace,
  cheshire-cat artifacts (venv, benchmarks, test output), jinja templates
- Sanitized .env.example: replaced real webhook URL and user ID with placeholders
- Removed SECRETS_CONFIGURED.md (contained sensitive token info)
- Removed bot/static/system.html.bak (stale backup)
- Removed bot/utils/voice_receiver.py.old (superseded)
2026-03-04 00:17:05 +02:00
a226bc41df Rewrite is_miku_addressed() to only trigger when addressed, not mentioned
- Pre-compile 393 name variants into 4 regex patterns at module load
  (was 7,300+ raw re.search() calls per message)
- Strict addressing detection using punctuation context:
  START:  name at beginning + punctuation (Miku, ... / みく!...)
  END:    comma + name at end (..., Miku / ...、ミク)
  MIDDLE: commas on both sides - vocative (..., Miku, ...)
  ALONE:  name is the entire message (Miku! / ミクちゃん)
- Rejects mere mentions: 'I like Miku' / 'Miku is cool' no longer trigger
- Script-family-aware pattern generation (Latin, Cyrillic, Japanese)
  eliminates nonsensical cross-script combos (e.g. o-みく)
- Word boundary enforcement prevents substring matches (mikumiku)
- Fixes regex 'unbalanced parenthesis' errors from old implementation
- Add comprehensive test suite (94 cases, all passing)
2026-03-03 12:42:33 +02:00
892edf5564 feat: Last Prompt shows full prompt with evil mode awareness
- discord_bridge before_agent_starts now checks evil_mode from
  working_memory to load the correct personality files:
  Normal: miku_lore/prompt/lyrics + /app/moods/{mood}.txt
  Evil: evil_miku_lore/prompt/lyrics + /app/moods/evil/{mood}.txt
- Reads files directly instead of relying on cross-plugin working_memory
- cat_client.query() returns (response, full_prompt) tuple
- Full prompt includes system prefix + recalled memories + conversation
- API /prompt/cat returns full_prompt field
2026-03-01 01:17:06 +02:00
a0a16e6784 fix: resolve Cat personality startup race condition
Bot was calling restore_evil_cat_state() in on_ready() before Cheshire
Cat finished booting (~25s), causing all plugin toggle API calls to fail
silently. Evil Miku plugin was left disabled and the bot used Cat's
default personality instead.

Changes:
- cat_client.py: add wait_for_ready() that polls Cat health endpoint
  every 5s for up to 120s before attempting any admin API calls
- evil_mode.py: rewrite restore_evil_cat_state() with:
  - wait_for_ready() gate before any plugin/model switching
  - 3-second extra delay after Cat is up (plugin registry fully loaded)
  - up to 3 retries on failure
  - post-switch verification that the correct plugins are actually active

Also fixes helcyon model references that leaked into the container image
(cat_client.py was switching Cat's LLM to 'helcyon' which has no
llama-swap handler; reverted to correct 'darkidol' / 'llama3.1').
2026-03-01 00:57:13 +02:00
f0b5d71097 feat: add loading spinners on tab switch for data-driven tabs
Show a CSS spinner overlay when switching to Autonomous Stats (tab6),
Memories (tab9), and DM Management (tab10). Spinner only shows on
first visit when content is empty, removed after data loads.
2026-03-01 00:29:03 +02:00
0cdf26dc34 feat: populate all mood dropdowns dynamically from API
Replace hardcoded <option> lists in #mood (tab1 DM mood) and
#chat-mood-select (tab7 chat mood) with empty selects populated
by populateMoodDropdowns(). Respects evil mode emoji mapping.
Called on DOMContentLoaded and after server cards render.
2026-03-01 00:28:07 +02:00
1037d13b0a feat: reorganize tabs + add Last Prompt CC/Fallback toggle
- Split Status tab: moved DM management to new dedicated 📱 DM Management tab
- Added Last Prompt source toggle (Cheshire Cat / Bot Fallback) with
  localStorage persistence, CC as default
- Backend: added LAST_CAT_INTERACTION global, /prompt/cat API endpoint
- Bot tracks Cat interactions (prompt, response, user, mood, timestamp)
- Auto-load data on tab switch (Status loads prompt, DM tab loads users)
2026-03-01 00:26:22 +02:00
5bdd907730 refactor: standardize raw fetch() calls to use apiCall() wrapper
Convert 47 raw fetch+response.json+error-handling patterns to use the
centralized apiCall() utility. The 11 remaining raw fetch() calls are
FormData uploads or SSE streaming that require direct fetch access.
2026-03-01 00:14:08 +02:00
820a226dd9 refactor: consolidate 3 DOMContentLoaded listeners into single init block
- Extract initTabState, initTabWheelScroll, initVisibilityPolling,
  initChatImagePreview, initModalAccessibility as named functions
- Move polling interval vars to outer scope for accessibility
- Single DOMContentLoaded calls all init functions in logical order
- Replace scattered listeners with comment markers at original locations
2026-02-28 23:50:40 +02:00
e0dc190710 feat: add responsive CSS breakpoints for mobile and tablet support
- 1200px: Adjust panel widths to 55/45
- 1024px: Stack panels vertically, logs below main content
- 768px: Tab buttons flow into auto-fill grid rows
- 480px: Two-column tab grid, reduced padding for small screens
2026-02-28 23:48:23 +02:00
191a368258 fix: prevent XSS in addChatMessage by using textContent for user input
- Escape sender name via escapeHtml in innerHTML template
- Set message content via textContent instead of innerHTML injection
- Prevents HTML/script injection from user input or LLM responses
2026-02-28 23:32:28 +02:00
7a10206617 feat: modal UX - close on Escape key and backdrop click, add ARIA attributes
- Escape key closes any open memory modal
- Clicking the dark backdrop behind a modal closes it
- Add role=dialog, aria-modal, aria-label for accessibility
2026-02-28 23:31:28 +02:00
8b96f4dc8a cleanup: remove duplicate escapeHtml function, add null check to remaining one 2026-02-28 23:30:05 +02:00
4666986f78 cleanup: remove ~70 lines of duplicate CSS for conversation view styles
First block of conversation-view, conversations-list, conversation-message,
message-header, sender, timestamp, message-content, message-attachments was
silently overridden by identical selectors defined later. Kept the unique
reaction/delete-button styles.
2026-02-28 23:29:15 +02:00
5e002004cc fix: notification system - timer race condition, success color, z-index above modals
- Cancel previous timer before starting new one (prevents early dismissal)
- Add green background for type='success' notifications
- Bump z-index from 1000 to 3000 so notifications show above modals
- Add fade-out transition for smoother dismissal
2026-02-28 23:28:30 +02:00
d3fb0eacb6 fix: updateBedtimeRange variable scoping - originalText accessible in finally block 2026-02-28 23:26:02 +02:00
7bcb670b96 perf: pause polling intervals when browser tab is hidden
- Replace raw setInterval with startPolling/stopPolling functions
- Add visibilitychange listener to pause when tab is hidden
- Immediately refresh data when tab becomes visible again
- Saves bandwidth and CPU when the dashboard is in background
2026-02-28 23:25:07 +02:00
a434f11561 fix: add viewport meta tag for responsive support 2026-02-28 23:14:32 +02:00
a217f18649 fix: add missing create-memory-collection hidden input to Create Memory modal 2026-02-28 23:13:50 +02:00
ed9df5ff81 fix: resetServerMood variable scoping - originalText accessible in finally block 2026-02-28 23:12:44 +02:00
6a35718a7c feat: enable mouse wheel horizontal scrolling on tab bar 2026-02-28 23:09:09 +02:00
e2077705de fix: improve log panel with auto-scroll and color-coded lines 2026-02-28 23:05:26 +02:00
8ca94fbafc fix: persist active tab via localStorage + fix implicit event bug in switchTab
- Add data-tab attributes to tab buttons for reliable identification
- Replace implicit window.event usage with querySelector by data-tab
- Save active tab to localStorage on switch, restore on page load
2026-02-28 22:59:12 +02:00
66881f4c88 refactor: deduplicate prompts, reorganize persona files, update paths
Prompt deduplication (~20% reduction, 4,743 chars saved):
- evil_miku_lore.txt: remove intra-file duplication (height rule 2x,
  cruelty-has-substance 2x, music secret 2x, adoration secret 2x),
  trim verbose restatements, cut speech examples from 10 to 6
- evil_miku_prompt.txt: remove entire PERSONALITY section (in lore),
  remove entire RESPONSE STYLE section (now only in preamble),
  soften height from prohibition to knowledge
- miku_lore.txt: remove RELATIONSHIPS section (duplicates FRIENDS)
- miku_prompt.txt: remove duplicate intro, 4 personality traits
  already in lore, FAMOUS SONGS section (in lore), fix response
  length inconsistency (1-2 vs 2-3 -> consistent 2-3)

Preamble updates (evil_mode.py, evil_miku_personality.py, llm.py,
miku_personality.py):
- Response rules now exist in ONE place only (preamble)
- Height rule softened: model knows 15.8m, can say it if asked,
  but won't default to quoting it when taunting
- Response length: 2-4 sentences (was 1-3), removed action template
  list that model was copying literally (*scoffs*, *rolls eyes*)
- Added: always include actual words, never action-only responses
- Normal Miku: trim CHARACTER CONTEXT, fix 1-3 -> 2-3 sentences

Directory reorganization:
- Move 6 persona files to bot/persona/{evil,miku}/ subdirectories
- Update all open() paths in evil_mode.py, context_manager.py,
  voice_manager.py, both Cat plugins
- Dockerfile: 6 COPY lines -> 1 (COPY persona /app/persona)
- docker-compose: 6 file mounts -> 2 directory mounts
  (bot/persona/evil -> cat/data/evil, bot/persona/miku -> cat/data/miku)

Evil Miku system (previously unstaged):
- Full evil mood management: 2h rotation timer, mood persistence,
  10 mood-specific autonomous template pools, mood-aware DMs
- Evil mode toggle with role color/nickname/pfp management
- get_evil_system_prompt() with mood integration

Add test_evil_moods.py: 10-mood x 3-message comprehensive test
2026-02-27 13:14:03 +02:00
9038f442a3 feat(evil-miku): add 10-mood system and Evil Miku Cat plugin
- Add 6 new evil mood files: bored, contemptuous, jealous, manic,
  melancholic, playful_cruel
- Rewrite 4 existing mood files: aggressive, cunning, evil_neutral,
  sarcastic (shorter, more focused descriptions)
- Add evil_miku_personality Cat plugin (parallel to miku_personality)
  with mood-aware system prompt, softened height rule, and balanced
  response length rules (2-4 sentences)
2026-02-27 13:11:37 +02:00
7aafd06da1 added new evil mood emoji map to web UI and minor fixes 2026-02-26 12:08:41 +02:00
9e5511da21 perf: reduce container sizes and build times
- miku-stt: switch PyTorch CUDA -> CPU-only (~2.5 GB savings)
  - Silero VAD already runs on CPU via ONNX (onnx=True), CUDA PyTorch was waste
  - faster-whisper/CTranslate2 uses CUDA directly, no PyTorch GPU needed
  - torch+torchaudio layer: 3.3 GB -> 796 MB; total image 9+ GB -> 6.83 GB
  - Tested: Silero VAD loads (ONNX), Whisper loads on cuda, server ready

- llama-swap-rocm: add root .dockerignore to fix 31 GB build context
  - Dockerfile clones all sources from git, never COPYs from context
  - 19 GB of GGUF model files were being transferred on every build
  - Now excludes everything (*), near-zero context transfer

- anime-face-detector: add .dockerignore to exclude accumulated outputs
  - api/outputs/ (56 accumulated detection files) no longer baked into image
  - api/__pycache__/ and images/ also excluded

- .gitignore: remove .dockerignore exclusion so these files are tracked
2026-02-25 14:41:04 +02:00
0edf1ef1c0 Fix webhook avatar mismatch: pass avatar_url at send time
- Fixed missing client parameter in animated GIF webhook update path
- Added get_persona_avatar_urls() helper that returns bot's current Discord
  avatar URL for Miku persona (always fresh, no cache lag)
- Pass avatar_url on every webhook.send() call in bipolar_mode.py,
  persona_dialogue.py, and api.py so avatars always match current pfp
  regardless of webhook cache state
2026-02-25 13:20:18 +02:00
9b74acd03b Fix missing sklearn module in miku-bot; upgrade miku-stt to CUDA 12.8.1 + PyTorch 2.7.1
- miku-bot: Re-add scikit-learn to requirements.txt (needed for vision color extraction)
- miku-stt: Upgrade from CUDA 12.6.2 to 12.8.1, PyTorch 2.5.1 to 2.7.1 per RealtimeSTT PR #295
- miku-stt: Use Ubuntu 24.04 with Python 3.12 (single installation, no dual Python)
- miku-stt: Add requirements-gpu-torch.txt for separate PyTorch installation
- miku-stt: Use --break-system-packages flag for Ubuntu 24.04 pip compatibility
2026-02-23 14:31:48 +02:00
615dd4a5ef fix(P3): 3 priority-3 fixes — timezone, decay rounding, rate limiter
#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.
2026-02-23 13:53:22 +02:00
2b743ed65e fix(P2): 5 priority-2 bug fixes — emoji consolidation, DM safety, pause gap
#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.
2026-02-23 13:43:15 +02:00
0e4aebf353 fix(P1): 6 priority-1 bug fixes for autonomous engine and mood system
#4  Sleep/mood desync — set_server_mood() now clears is_sleeping when
    mood changes away from 'asleep', preventing ghost-sleep state.

#5  Race condition in _check_and_act — added per-guild asyncio.Lock so
    overlapping ticks + message-triggered calls cannot fire concurrently.

#6  Class-level attrs on ServerConfig — sleepy_responses_left,
    angry_wakeup_timer, and forced_angry_until are now proper dataclass
    fields with defaults, so asdict()/from_dict() round-trip correctly.
    Also strips unknown keys in from_dict() to survive schema changes.

#7  Persistence decay_factor crash — initialise decay_factor = 1.0
    before the loop so empty-server or zero-downtime paths don't
    raise NameError.

#8  Double record_action — removed the redundant call in
    autonomous_tick_v2(); only _check_and_act records the action now.

#9  Engine mood desync — on_mood_change() is now called inside
    set_server_mood() (single source of truth) and removed from 4
    call-sites in api.py, moods.py, and server_manager wakeup task.
2026-02-23 13:31:15 +02:00
422366df4c fix: 3 critical autonomous engine & mood system bugs
1. Momentum cliff at 10 messages (P0): The conversation momentum formula
   had a discontinuity where the 10th message caused momentum to DROP from
   0.9 to 0.5. Replaced with a smooth log1p curve that monotonically
   increases (0→0→0.20→0.32→...→0.70→0.89→1.0 at 30 msgs).

2. Neutral keywords overriding all moods (P0): detect_mood_shift() checked
   neutral early with generic keywords (okay, sure, hmm) that matched
   almost any response, constantly resetting mood to neutral. Now: all
   specific moods are scored by match count first (best-match wins),
   neutral is only checked as fallback and requires 2+ keyword matches.

3. Uncancellable delayed_wakeup tasks (P0): Fire-and-forget sleep tasks
   could stack and overwrite mood state after manual wake-up. Added a
   centralized wakeup task registry in ServerManager with automatic
   cancellation on manual wake or new sleep cycle.
2026-02-20 15:37:57 +02:00
2f0d430c35 feat: Add manual trigger bypass for web UI autonomous engagement
- 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
2026-02-20 00:53:42 +02:00
9972edb06d fix(docker): add config_manager.py to Dockerfile and logger components
- Add COPY config_manager.py to Dockerfile so it's included in the image
- Add 'config_manager' to logger COMPONENTS list to enable logging

Fixes the ModuleNotFoundError and ValueError when importing config_manager
2026-02-19 11:02:58 +02:00
305605fde5 docs: add comprehensive COMMANDS.md reference
Document all bot commands, features and API endpoints:
- 7 voice commands, 4 UNO commands, 2 inline commands
- Conversational features (name detection, DMs, media analysis, image gen)
- Mood system (14 regular + 4 evil moods)
- Personality modes (evil, bipolar, persona dialogue)
- Voice chat architecture (dual GPU, STT, TTS, resource locking)
- Autonomous behavior system (6 action types)
- Memory system (Cheshire Cat declarative + episodic)
- Profile picture system
- ~126 API endpoints organized into 20 categories
- Discord event handlers and environment variables

Resolves #18
2026-02-18 12:37:25 +02:00
d44f08af18 fix(config): persist runtime settings across bot restarts
Add restore_runtime_settings() to ConfigManager that reads config_runtime.yaml
on startup and restores persisted values into globals:
- LANGUAGE_MODE, AUTONOMOUS_DEBUG, VOICE_DEBUG_MODE
- USE_CHESHIRE_CAT, PREFER_AMD_GPU, DM_MOOD

Add missing persistence calls to API endpoints:
- POST /language/set now persists to config_runtime.yaml
- POST /voice/debug-mode now persists to config_runtime.yaml
- POST /memory/toggle now persists to config_runtime.yaml

Call restore_runtime_settings() in on_ready() after evil/bipolar restore.

Resolves #22
2026-02-18 12:18:12 +02:00
8d5137046c fix(shutdown): implement graceful async shutdown handler
Replace the minimal sync-only shutdown (which only saved autonomous state)
with a comprehensive async graceful_shutdown() coroutine that:

1. Ends active voice sessions (disconnect, release GPU locks, cleanup audio)
2. Saves autonomous engine state
3. Stops the APScheduler
4. Cancels all tracked background tasks (from task_tracker)
5. Closes the Discord gateway connection

Signal handlers (SIGTERM/SIGINT) now schedule the async shutdown on the
running event loop. The atexit handler is kept as a last-resort sync fallback.

Resolves #5, also addresses #4 (voice cleanup at shutdown)
2026-02-18 12:08:32 +02:00
7b7abcfc68 fix(tasks): replace fire-and-forget asyncio.create_task with create_tracked_task
Add utils/task_tracker.py with create_tracked_task() that wraps background
tasks with error logging, cancellation handling, and reference tracking.

Replace all 17 fire-and-forget asyncio.create_task() calls across 7 files:
- bot/bot.py (5 interjection checks)
- bot/utils/autonomous.py (2 check-and-act/react tasks)
- bot/utils/bipolar_mode.py (3 argument tasks)
- bot/commands/uno.py (1 game loop task)
- bot/utils/voice_receiver.py (3 STT/interruption callbacks)
- bot/utils/persona_dialogue.py (4 dialogue turn/interjection tasks)

Previously-tracked tasks (voice_audio.py, voice_manager.py) were left as-is
since they already store task references for cancellation.

Closes #1
2026-02-18 12:01:08 +02:00