# 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: 1. The `should_take_action()` method in `autonomous_engine.py` didn'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) 2. **The main bug**: `_check_and_act()` was calling `autonomous_tick_v2()`, which then called `should_take_action()` **again** without the `triggered_by_message` flag. 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: 1. `_check_and_act()` calls `should_take_action(triggered_by_message=True)` → returns `"join_conversation"` 2. Calls `autonomous_tick_v2()` 3. `autonomous_tick_v2()` calls `should_take_action()` **again** (without flag) → returns `"general"` 4. 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 = False` parameter to `should_take_action()` - Modified the "break silence" decision logic to check this flag - When `triggered_by_message=True` and "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: 1. Pass `triggered_by_message=True` when calling `should_take_action()` 2. **Execute the action directly** instead of calling `autonomous_tick_v2()` (which would check again) 3. Include rate limiting and error handling - 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: 1. **join_conversation** - High conversation momentum 2. **engage_user** - User activity detected (status change, started activity) 3. **join_conversation (FOMO)** - Lots of messages without Miku participating 4. **general OR join_conversation** - Break silence (depends on `triggered_by_message` flag) 5. **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: 1. Have Miku idle for a while (to meet "break silence" condition) 2. Send a message in the autonomous channel 3. If Miku responds, she should now reply to your message instead of saying something random ## Date December 5, 2025