fix: separate context from new messages so prior-cycle chat doesn't inflate scores

The conversation analysis was re-scoring old messages alongside new ones,
causing users to get penalized repeatedly for already-scored messages.
A "--- NEW MESSAGES ---" separator now marks which messages are new, and
the prompt instructs the LLM to score only those. Also fixes bot-mention
detection to require an explicit @mention in message text rather than
treating reply-pings as scans (so toxic replies to bot warnings aren't
silently skipped).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-25 15:48:02 -05:00
parent 8734f1883b
commit 7417908142
3 changed files with 31 additions and 17 deletions

View File

@@ -383,12 +383,16 @@ class LLMClient:
def _format_conversation_block(
messages: list[tuple[str, str, datetime, str | None]],
now: datetime | None = None,
new_message_start: int | None = None,
) -> str:
"""Format messages as a compact timestamped chat block.
Each tuple is (username, content, timestamp, reply_to_username).
Consecutive messages from the same user collapse to indented lines.
Replies shown as ``username → replied_to:``.
If *new_message_start* is given, a separator is inserted before that
index so the LLM can distinguish context from new messages.
"""
if now is None:
now = datetime.now(timezone.utc)
@@ -396,7 +400,12 @@ class LLMClient:
lines = [f"[Current time: {now.strftime('%I:%M %p')}]", ""]
last_user = None
for username, content, ts, reply_to in messages:
for idx, (username, content, ts, reply_to) in enumerate(messages):
if new_message_start is not None and idx == new_message_start:
lines.append("")
lines.append("--- NEW MESSAGES (score only these) ---")
lines.append("")
last_user = None # reset collapse so first new msg gets full header
delta = now - ts.replace(tzinfo=timezone.utc) if ts.tzinfo is None else now - ts
rel = LLMClient._format_relative_time(delta)
@@ -425,12 +434,13 @@ class LLMClient:
mention_context: str = "",
channel_context: str = "",
user_notes_map: dict[str, str] | None = None,
new_message_start: int | None = None,
) -> dict | None:
"""Analyze a conversation block in one call, returning per-user findings."""
if not messages:
return None
convo_block = self._format_conversation_block(messages)
convo_block = self._format_conversation_block(messages, new_message_start=new_message_start)
user_content = f"=== CONVERSATION BLOCK ===\n{convo_block}\n\n"
if user_notes_map: