3.4 KiB
Autonomous Message Response Fix
Problem
When Miku's autonomous system decided to respond immediately after someone sent a message, she would sometimes say something general/random instead of responding to what the person said. This happened because the decision engine could return "general" action type even when triggered by a fresh message.
Root Cause
The issue had two parts:
-
The
should_take_action()method inautonomous_engine.pydidn't distinguish between:- Scheduled checks - Running periodically on a timer (appropriate for "general" actions)
- Message-triggered checks - Running immediately after someone sends a message (should respond to that message)
-
The main bug:
_check_and_act()was callingautonomous_tick_v2(), which then calledshould_take_action()again without thetriggered_by_messageflag. This caused the decision to be re-evaluated and potentially changed from"join_conversation"to"general".
When the "break silence" condition was met, the flow was:
_check_and_act()callsshould_take_action(triggered_by_message=True)→ returns"join_conversation"- Calls
autonomous_tick_v2() autonomous_tick_v2()callsshould_take_action()again (without flag) → returns"general"- Executes general action instead of joining conversation
Solution
Added a triggered_by_message parameter to the decision logic:
Changes Made
1. autonomous_engine.py
- Added
triggered_by_message: bool = Falseparameter toshould_take_action() - Modified the "break silence" decision logic to check this flag
- When
triggered_by_message=Trueand "break silence" condition is met, return"join_conversation"instead of"general" - This ensures Miku responds to the recent message rather than saying something random
2. autonomous.py
- Updated
_check_and_act()to:- Pass
triggered_by_message=Truewhen callingshould_take_action() - Execute the action directly instead of calling
autonomous_tick_v2()(which would check again) - Include rate limiting and error handling
- Pass
- This prevents the decision from being re-evaluated and potentially changed
- Added documentation explaining the importance of direct execution
Behavior Changes
Before Fix
User: "Hey everyone, how's it going?"
Miku: "I wonder if there are clouds on Mars... 🤔" # Random general statement
After Fix
User: "Hey everyone, how's it going?"
Miku: "Hey! I'm doing great! How about you? 😊" # Responds to the message
Technical Details
The decision priority order remains:
- join_conversation - High conversation momentum
- engage_user - User activity detected (status change, started activity)
- join_conversation (FOMO) - Lots of messages without Miku participating
- general OR join_conversation - Break silence (depends on
triggered_by_messageflag) - share_tweet - Low activity, wants to share content
The key change is in step 4:
- Scheduled check (
triggered_by_message=False): Returns"general"- Miku says something random - Message-triggered check (
triggered_by_message=True): Returns"join_conversation"- Miku responds to recent messages
Testing
To verify the fix:
- Have Miku idle for a while (to meet "break silence" condition)
- Send a message in the autonomous channel
- If Miku responds, she should now reply to your message instead of saying something random
Date
December 5, 2025