75 lines
3.4 KiB
Markdown
75 lines
3.4 KiB
Markdown
# 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
|