Files
miku-discord/readmes/AUTONOMOUS_REACTIONS_FEATURE.md

6.5 KiB

Autonomous Reactions Feature

Overview

Miku now has the ability to autonomously react to messages with emojis selected by the LLM. This feature has two modes:

  1. Scheduled reactions: Every 20 minutes with a 50% chance
  2. Real-time reactions: 50% chance to react to each new message in the autonomous channel

How It Works

Scheduled Reactions

  • Frequency: Every 20 minutes (independent from other autonomous actions)
  • Probability: 50% chance each interval
  • Target: Randomly selects a recent message (last 50 messages, within 12 hours) from the autonomous channel
  • Emoji Selection: LLM chooses the most appropriate emoji based on message content

Real-Time Reactions

  • Trigger: Every new message posted in the autonomous channel
  • Probability: 50% chance per message
  • Target: The newly posted message
  • Emoji Selection: LLM chooses the most appropriate emoji based on message content

LLM-Based Emoji Selection

Instead of using mood-based emoji sets, Miku now asks the LLM to select the most contextually appropriate emoji for each message. The LLM considers:

  • Message content and tone
  • Context and sentiment
  • Natural reaction patterns

This makes reactions feel more natural and appropriate to the specific message content, regardless of Miku's current mood.

Behavior Details

Message Selection Criteria (Scheduled)

  • Only reacts to messages from other users (not her own)
  • Only considers messages less than 12 hours old
  • Randomly selects from up to 50 recent messages
  • Skips the action if no suitable messages are found

Real-Time Reaction Criteria

  • Only triggers in the autonomous channel
  • Only for messages from other users (not Miku's own)
  • 50% probability per message
  • Reacts immediately to the new message

Special Cases

  • When Asleep: Miku will not react to messages when her mood is "asleep" or when she's in sleep mode
  • Permissions: If the bot lacks "Add Reactions" permission in a channel, it will log an error but continue normally
  • Invalid Emoji: If LLM returns an invalid response, falls back to 💙

Manual Triggering

From the Web UI

  1. Open the Miku Control Panel (http://your-server:3939)
  2. Go to the Actions tab
  3. Select a target server (or "All Servers")
  4. Click the "React to Message" button

API Endpoint

POST /autonomous/reaction
Content-Type: application/json

{
  "guild_id": 123456789  # Optional - omit to trigger for all servers
}

Response:

{
  "status": "ok",
  "message": "Autonomous reaction queued for server 123456789"
}

Technical Implementation

Scheduler Configuration

  • Job ID: autonomous_reaction_{guild_id}
  • Trigger: IntervalTrigger (every 20 minutes)
  • Probability: 50% chance each interval
  • Independence: Runs on a separate schedule from autonomous speaking (15 min), conversation detection (3 min), etc.

Function Flow (Scheduled)

  1. Scheduler triggers every 20 minutes
  2. 50% probability check - may skip
  3. Queues async task miku_autonomous_reaction_for_server() in bot's event loop
  4. Fetches recent messages from autonomous channel (50 messages, 12 hour window)
  5. Filters out bot's own messages and old messages
  6. Randomly selects a message
  7. Asks LLM to choose appropriate emoji
  8. Adds reaction to the selected message

Function Flow (Real-Time)

  1. User posts message in autonomous channel
  2. Bot's on_message event fires
  3. 50% probability check - may skip
  4. Immediately calls miku_autonomous_reaction_for_server() with the new message
  5. Asks LLM to choose appropriate emoji
  6. Adds reaction to the new message

File Changes

  • bot/utils/autonomous.py:
    • Updated miku_autonomous_reaction_for_server() with:
      • 50% probability check
      • 12-hour message window (was 2 hours)
      • LLM-based emoji selection (was mood-based)
      • force_message parameter for real-time reactions
  • bot/bot.py:
    • Added real-time reaction trigger in on_message event
    • 50% chance to react to new messages in autonomous channel
  • bot/server_manager.py: Added _run_autonomous_reaction_for_server() and scheduler job setup
  • bot/api.py: Added /autonomous/reaction POST endpoint
  • bot/static/index.html: Added "React to Message" button in Actions tab

Benefits

Dual-Mode System

  • Scheduled: Keeps old messages engaged, prevents dead conversation feel
  • Real-Time: Provides immediate feedback to active users

LLM-Powered Intelligence

  • Reactions are contextually appropriate to message content
  • Not limited to mood-based emoji sets
  • More natural and varied interaction style
  • Adapts to different types of messages

Probability-Based

  • 50% chance prevents over-reacting
  • Feels more natural and human-like
  • Doesn't overwhelm chat with reactions

Server-Specific

  • Each server has its own reaction schedule
  • Independent tracking per server
  • Only reacts in designated autonomous channels

Monitoring

Check the bot logs for autonomous reaction activity:

Scheduled reactions:

🎲 Autonomous reaction skipped for server 123456789 (50% chance)
✅ Autonomous reaction queued for server 123456789
✅ Autonomous reaction: Added 😊 to message from Username in ServerName

Real-time reactions:

🎯 Reacting to new message from Username
✅ Autonomous reaction: Added 🎉 to message from Username in ServerName

Error messages:

❌ Missing permissions to add reactions in server 123456789
📭 No recent messages to react to in server 123456789
💤 Miku is asleep in server 123456789, skipping autonomous reaction
⚠️ LLM returned invalid emoji, using fallback: 💙

Configuration

Change Scheduled Interval

Edit bot/server_manager.py in the setup_server_scheduler() function:

scheduler.add_job(
    self._run_autonomous_reaction_for_server,
    IntervalTrigger(minutes=20),  # Change this value
    args=[guild_id, client],
    id=f"autonomous_reaction_{guild_id}"
)

Change Probabilities

Edit bot/utils/autonomous.py in miku_autonomous_reaction_for_server():

if force_message is None and random.random() > 0.5:  # Change 0.5 to adjust probability

Edit bot/bot.py in the on_message event:

if not is_dm and message.guild and random.random() <= 0.5:  # Change 0.5 to adjust probability

Change Message History Window

Edit bot/utils/autonomous.py in miku_autonomous_reaction_for_server():

if age > 43200:  # Change 43200 (12 hours in seconds)

Then restart the bot for changes to take effect.