269 lines
8.0 KiB
Markdown
269 lines
8.0 KiB
Markdown
|
|
# Critical Fixes for Autonomous V2 - Spam Prevention
|
||
|
|
|
||
|
|
**Date**: November 23, 2025
|
||
|
|
**Issue**: Miku sending multiple rapid-fire messages on startup and reacting to messages in wrong channels
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🐛 Issues Identified
|
||
|
|
|
||
|
|
### Issue #1: No Channel Filtering ❌
|
||
|
|
**Problem**: `on_message_event()` was processing ALL messages from ALL channels in the server.
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- Miku reacted to messages in channels she shouldn't monitor
|
||
|
|
- Wasted processing on irrelevant messages
|
||
|
|
- Privacy concern: tracking messages from non-autonomous channels
|
||
|
|
|
||
|
|
**Logs showed**:
|
||
|
|
```
|
||
|
|
bot-1 | 🎯 [V2] Real-time reaction triggered for message from aryan slavic eren yigger
|
||
|
|
bot-1 | ❌ [j's reviews patreon server (real)] Missing permissions to add reactions
|
||
|
|
```
|
||
|
|
This means she tried to react to a message in a channel where she doesn't have permissions (not the autonomous channel).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #2: No Startup Cooldown ❌
|
||
|
|
**Problem**: On bot startup, the autonomous system immediately started making decisions, causing 3 messages to be sent back-to-back.
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- Spam: 3 general messages in ~6 seconds
|
||
|
|
- Bad user experience
|
||
|
|
- Looks like a bug, not natural conversation
|
||
|
|
|
||
|
|
**Logs showed**:
|
||
|
|
```
|
||
|
|
bot-1 | 🎯 [V2] Message triggered autonomous action: general
|
||
|
|
bot-1 | 🤖 [V2] Autonomous engine decided to: general for server 1140377616667377725
|
||
|
|
bot-1 | 💬 Miku said something general in #general
|
||
|
|
bot-1 | 🎯 [V2] Message triggered autonomous action: general
|
||
|
|
bot-1 | 🤖 [V2] Autonomous engine decided to: general for server 1140377616667377725
|
||
|
|
bot-1 | 💬 Miku said something general in #general
|
||
|
|
bot-1 | 🎯 [V2] Message triggered autonomous action: general
|
||
|
|
bot-1 | 🤖 [V2] Autonomous engine decided to: general for server 1140377616667377725
|
||
|
|
bot-1 | 💬 Miku said something general in #general
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Issue #3: No Rate Limiting ❌
|
||
|
|
**Problem**: Even with the decision engine, multiple messages could trigger actions in quick succession if conditions were met.
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- Potential for spam if multiple users send messages simultaneously
|
||
|
|
- No protection against edge cases
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ Fixes Applied
|
||
|
|
|
||
|
|
### Fix #1: Channel Filtering 🔒
|
||
|
|
**File**: `bot/utils/autonomous.py`
|
||
|
|
|
||
|
|
**Added**: Server config check to only process messages from the autonomous channel
|
||
|
|
|
||
|
|
```python
|
||
|
|
def on_message_event(message):
|
||
|
|
"""
|
||
|
|
ONLY processes messages from the configured autonomous channel.
|
||
|
|
"""
|
||
|
|
if not message.guild:
|
||
|
|
return # DMs don't use this system
|
||
|
|
|
||
|
|
guild_id = message.guild.id
|
||
|
|
|
||
|
|
# Get server config to check if this is the autonomous channel
|
||
|
|
server_config = server_manager.get_server_config(guild_id)
|
||
|
|
if not server_config:
|
||
|
|
return # No config for this server
|
||
|
|
|
||
|
|
# CRITICAL: Only process messages from the autonomous channel
|
||
|
|
if message.channel.id != server_config.autonomous_channel_id:
|
||
|
|
return # Ignore messages from other channels
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- ✅ Only tracks messages from the configured autonomous channel
|
||
|
|
- ✅ Won't react to messages in other channels
|
||
|
|
- ✅ Privacy: doesn't process messages from non-autonomous channels
|
||
|
|
- ✅ Performance: less unnecessary processing
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #2: Startup Cooldown ⏳
|
||
|
|
**File**: `bot/utils/autonomous_engine.py`
|
||
|
|
|
||
|
|
**Added**: 2-minute cooldown after bot startup
|
||
|
|
|
||
|
|
```python
|
||
|
|
class AutonomousEngine:
|
||
|
|
def __init__(self):
|
||
|
|
# ... existing code ...
|
||
|
|
self.bot_startup_time: float = time.time() # Track when bot started
|
||
|
|
```
|
||
|
|
|
||
|
|
```python
|
||
|
|
def should_take_action(self, guild_id: int, debug: bool = False) -> Optional[str]:
|
||
|
|
# STARTUP COOLDOWN: Don't act for first 2 minutes after bot startup
|
||
|
|
# This prevents rapid-fire messages when bot restarts
|
||
|
|
time_since_startup = time.time() - self.bot_startup_time
|
||
|
|
if time_since_startup < 120: # 2 minutes
|
||
|
|
if debug:
|
||
|
|
print(f"⏳ [V2 Debug] Startup cooldown active ({time_since_startup:.0f}s / 120s)")
|
||
|
|
return None
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- ✅ Bot waits 2 minutes after startup before taking any autonomous actions
|
||
|
|
- ✅ Gives time for context to build naturally
|
||
|
|
- ✅ Prevents immediate spam on restart
|
||
|
|
- ✅ Users won't see weird behavior when bot comes online
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### Fix #3: Rate Limiting 🛡️
|
||
|
|
**File**: `bot/utils/autonomous.py`
|
||
|
|
|
||
|
|
**Added**: Minimum 30-second interval between autonomous actions
|
||
|
|
|
||
|
|
```python
|
||
|
|
# Rate limiting: Track last action time per server to prevent rapid-fire
|
||
|
|
_last_action_execution = {} # guild_id -> timestamp
|
||
|
|
_MIN_ACTION_INTERVAL = 30 # Minimum 30 seconds between autonomous actions
|
||
|
|
|
||
|
|
async def autonomous_tick_v2(guild_id: int):
|
||
|
|
# Rate limiting check
|
||
|
|
now = time.time()
|
||
|
|
if guild_id in _last_action_execution:
|
||
|
|
time_since_last = now - _last_action_execution[guild_id]
|
||
|
|
if time_since_last < _MIN_ACTION_INTERVAL:
|
||
|
|
print(f"⏱️ [V2] Rate limit: Only {time_since_last:.0f}s since last action")
|
||
|
|
return
|
||
|
|
|
||
|
|
# ... execute action ...
|
||
|
|
|
||
|
|
# Update rate limiter
|
||
|
|
_last_action_execution[guild_id] = time.time()
|
||
|
|
```
|
||
|
|
|
||
|
|
**Impact**:
|
||
|
|
- ✅ Even if multiple messages trigger decisions, only 1 action per 30 seconds
|
||
|
|
- ✅ Extra safety net beyond the engine's cooldowns
|
||
|
|
- ✅ Prevents edge cases where rapid messages could cause spam
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔄 Multi-Layer Protection
|
||
|
|
|
||
|
|
The system now has **3 layers** of spam prevention:
|
||
|
|
|
||
|
|
1. **Engine Cooldowns** (in autonomous_engine.py)
|
||
|
|
- Each decision type has its own cooldown (5 min, 15 min, 30 min, etc.)
|
||
|
|
- Mood-based thresholds
|
||
|
|
|
||
|
|
2. **Startup Cooldown** (NEW)
|
||
|
|
- 2-minute grace period after bot restart
|
||
|
|
- Prevents immediate actions on startup
|
||
|
|
|
||
|
|
3. **Rate Limiter** (NEW)
|
||
|
|
- Hard limit: 30 seconds minimum between ANY autonomous actions
|
||
|
|
- Final safety net
|
||
|
|
|
||
|
|
```
|
||
|
|
Message arrives → Channel check → Startup check → Engine decision → Rate limiter → Action
|
||
|
|
↓ ↓ ↓ ↓ ↓ ↓
|
||
|
|
All msgs Autonomous only <2min? Skip Apply logic <30s? Skip Execute
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🧪 Testing Checklist
|
||
|
|
|
||
|
|
After deploying these fixes:
|
||
|
|
|
||
|
|
- [ ] **Restart bot** - Should see no autonomous actions for 2 minutes
|
||
|
|
- [ ] **Send messages in autonomous channel** - Should be tracked and eventually trigger actions
|
||
|
|
- [ ] **Send messages in other channels** - Should be ignored completely
|
||
|
|
- [ ] **Rapid messages** - Should trigger at most 1 action per 30 seconds
|
||
|
|
- [ ] **Debug mode** - Should show "Startup cooldown active" for first 2 minutes
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 📊 Expected Behavior
|
||
|
|
|
||
|
|
### On Bot Startup
|
||
|
|
```
|
||
|
|
[Bot starts]
|
||
|
|
User: "hello"
|
||
|
|
[V2 tracks message but doesn't act - startup cooldown]
|
||
|
|
User: "how are you?"
|
||
|
|
[V2 tracks message but doesn't act - startup cooldown]
|
||
|
|
... 2 minutes pass ...
|
||
|
|
User: "anyone here?"
|
||
|
|
[V2 can now act if conditions are met]
|
||
|
|
Miku: "Hi everyone! ✨"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Message in Wrong Channel
|
||
|
|
```
|
||
|
|
[User sends message in #random-chat]
|
||
|
|
[V2 ignores - not the autonomous channel]
|
||
|
|
|
||
|
|
[User sends message in #general (autonomous channel)]
|
||
|
|
[V2 tracks and may act]
|
||
|
|
```
|
||
|
|
|
||
|
|
### Rate Limiting
|
||
|
|
```
|
||
|
|
18:00:00 - User message → Miku acts
|
||
|
|
18:00:15 - User message → V2 rate limited (only 15s)
|
||
|
|
18:00:25 - User message → V2 rate limited (only 25s)
|
||
|
|
18:00:35 - User message → V2 can act (30s+ passed)
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🔧 Configuration
|
||
|
|
|
||
|
|
### Adjust Startup Cooldown
|
||
|
|
In `bot/utils/autonomous_engine.py`, line ~238:
|
||
|
|
```python
|
||
|
|
if time_since_startup < 120: # Change 120 to desired seconds
|
||
|
|
```
|
||
|
|
|
||
|
|
**Recommended**: 120 seconds (2 minutes)
|
||
|
|
|
||
|
|
### Adjust Rate Limit
|
||
|
|
In `bot/utils/autonomous.py`, line ~15:
|
||
|
|
```python
|
||
|
|
_MIN_ACTION_INTERVAL = 30 # Change to desired seconds
|
||
|
|
```
|
||
|
|
|
||
|
|
**Recommended**: 30 seconds minimum
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## ✅ Validation
|
||
|
|
|
||
|
|
All syntax checks passed:
|
||
|
|
- ✅ `autonomous.py` - Syntax OK
|
||
|
|
- ✅ `autonomous_engine.py` - Syntax OK
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 🎯 Summary
|
||
|
|
|
||
|
|
**Before**:
|
||
|
|
- ❌ Processed all messages from all channels
|
||
|
|
- ❌ Immediately acted on bot startup (3 messages in seconds)
|
||
|
|
- ❌ No rate limiting
|
||
|
|
|
||
|
|
**After**:
|
||
|
|
- ✅ Only processes messages from configured autonomous channel
|
||
|
|
- ✅ 2-minute startup cooldown prevents immediate spam
|
||
|
|
- ✅ 30-second rate limit prevents rapid-fire actions
|
||
|
|
- ✅ Multi-layer protection ensures natural behavior
|
||
|
|
|
||
|
|
**The bot will now behave naturally and won't spam on startup!** 🎉
|