feat: add relevance-gated proactive replies
Replace random-only proactive reply logic with LLM relevance check. The bot now evaluates recent conversation context and user memory before deciding to jump in, then applies reply_chance as a second gate. Bump reply_chance values higher since the relevance filter prevents most irrelevant replies. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
52
cogs/chat.py
52
cogs/chat.py
@@ -226,16 +226,58 @@ class ChatCog(commands.Cog):
|
||||
ch_id = message.channel.id
|
||||
self._messages_since_reply[ch_id] = self._messages_since_reply.get(ch_id, 0) + 1
|
||||
cooldown = self.bot.config.get("modes", {}).get("proactive_cooldown_messages", 5)
|
||||
reply_chance = mode_config.get("reply_chance", 0.0)
|
||||
|
||||
if (
|
||||
self._messages_since_reply[ch_id] >= cooldown
|
||||
and reply_chance > 0
|
||||
and random.random() < reply_chance
|
||||
and message.content and message.content.strip()
|
||||
):
|
||||
should_reply = True
|
||||
is_proactive = True
|
||||
# Gather recent messages for relevance check
|
||||
recent_for_check = []
|
||||
try:
|
||||
async for msg in message.channel.history(limit=5, before=message):
|
||||
if msg.content and msg.content.strip() and not msg.author.bot:
|
||||
recent_for_check.append(
|
||||
f"{msg.author.display_name}: {msg.content[:200]}"
|
||||
)
|
||||
except discord.HTTPException:
|
||||
pass
|
||||
recent_for_check.reverse()
|
||||
recent_for_check.append(
|
||||
f"{message.author.display_name}: {message.content[:200]}"
|
||||
)
|
||||
|
||||
# Build memory context for users in recent messages
|
||||
memory_parts = []
|
||||
seen_users = set()
|
||||
for line in recent_for_check:
|
||||
name = line.split(":")[0]
|
||||
if name not in seen_users and message.guild:
|
||||
seen_users.add(name)
|
||||
member = discord.utils.find(
|
||||
lambda m, n=name: m.display_name == n,
|
||||
message.guild.members,
|
||||
)
|
||||
if member:
|
||||
profile = self.bot.drama_tracker.get_user_notes(member.id)
|
||||
if profile:
|
||||
memory_parts.append(f"{name}: {profile}")
|
||||
|
||||
memory_ctx = "\n".join(memory_parts) if memory_parts else ""
|
||||
|
||||
is_relevant = await self.bot.llm.check_reply_relevance(
|
||||
recent_for_check, memory_ctx,
|
||||
)
|
||||
|
||||
if is_relevant:
|
||||
reply_chance = mode_config.get("reply_chance", 0.0)
|
||||
if reply_chance > 0 and random.random() < reply_chance:
|
||||
should_reply = True
|
||||
is_proactive = True
|
||||
else:
|
||||
# Not relevant — partially reset cooldown so we check again sooner
|
||||
self._messages_since_reply[ch_id] = max(
|
||||
0, self._messages_since_reply[ch_id] - 3
|
||||
)
|
||||
|
||||
if not should_reply:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user