| Server IP : 157.230.181.24 / Your IP : 216.73.217.11 Web Server : Apache/2.4.58 (Ubuntu) System : Linux conductive 6.8.0-117-generic #117-Ubuntu SMP PREEMPT_DYNAMIC Tue May 5 19:26:24 UTC 2026 x86_64 User : ( 1000) PHP Version : 8.3.31 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /opt/aim-bots/ |
Upload File : |
"""Check whether a bot reply actually fits the current AIM thread."""
from __future__ import annotations
import re
STOP = {
"the", "a", "an", "to", "and", "or", "i", "you", "it", "is", "in", "of", "that", "for", "on",
"with", "be", "are", "was", "at", "as", "so", "but", "not", "my", "me", "we", "he", "she",
"they", "do", "did", "have", "has", "had", "this", "what", "just", "like", "get", "got", "all",
"if", "can", "would", "will", "your", "u", "ur", "r", "im", "its", "dont", "cant", "yeah",
"haha", "hahah", "lol", "rofl", "oh", "man", "well", "then", "about", "up", "out", "going",
}
FOLLOWUP_RE = re.compile(
r"^(y\??|why\??|wut\??|what\??|huh\??|how\??|who\??|when\??|where\??|"
r"really\??|wait\??|and\??|so\??)\.?$",
re.I,
)
GENERIC_ACK_RE = re.compile(
r"^(yeah|yep|yup|yea|ya|y|lol|lmao|rofl|rotfl|haha|hahah|hahaha|idk|dunno|"
r"umm+|oh+|hm+|mhm|k|ok+|okay|same|true|word|for sure|nice|niiice|maybe|"
r"not sure|no idea|i guess|prob|probably|i dunno|no clue|sorta|kinda|"
r"ig|ight|aight|sup|yo|hey|help|owned|smooth|wtf|umm|uh+)\.?!*$",
re.I,
)
def _clean(line: str) -> str:
line = re.sub(r"^\[[^\]]+\]\s*", "", line)
line = line.split("\n")[-1]
return re.sub(r"\s+", " ", line.strip())
def tokens(text: str) -> set[str]:
words = re.findall(r"[a-z0-9']{3,}", text.lower())
return {w for w in words if w not in STOP}
def is_followup(message: str) -> bool:
m = _clean(message)
if not m:
return False
if len(m.split()) <= 2 and FOLLOWUP_RE.match(m):
return True
if len(m) <= 4 and "?" in m:
return True
return bool(re.match(r"^(why|what|how|who|when|where|really|wait)\b", m, re.I)) and len(m.split()) <= 4
def last_assistant_line(history: list[dict] | None) -> str:
if not history:
return ""
for msg in reversed(history):
if msg.get("role") == "assistant":
return _clean(msg.get("content", ""))
return ""
def last_user_line(history: list[dict] | None, skip_current: bool = True) -> str:
if not history:
return ""
users = [m for m in history if m.get("role") == "user"]
if skip_current and users:
users = users[:-1]
return _clean(users[-1]["content"]) if users else ""
def recent_context_text(history, limit: int = 6) -> str:
if not history:
return ""
msgs = list(history)[-limit:]
chunks = []
for msg in msgs:
text = _clean(msg.get("content", ""))
if text:
chunks.append(text)
return " ".join(chunks).lower()
def reply_coherent(
user_message: str,
reply: str,
history=None,
) -> bool:
"""Return False when an archive/LLM line is a non-sequitur for this thread."""
try:
user = _clean(user_message)
reply = reply.strip()
if not reply:
return False
hist = list(history) if history else []
if GENERIC_ACK_RE.match(reply.split("|")[0].strip()):
return True
ctx = recent_context_text(hist)
reply_lower = reply.lower()
reply_toks = tokens(reply)
if is_followup(user):
prev = last_assistant_line(hist)
if not prev:
return True
prev_toks = tokens(prev)
overlap = reply_toks & prev_toks
if overlap:
return True
names = re.findall(r"\b[A-Z][a-z]{2,}\b", prev)
for name in names:
if name.lower() in reply_lower:
return True
if re.search(r"\b(she|her|he|him|they|them)\b", reply_lower):
if re.search(r"\b(amy|txt|text|message|mom|dad|joy|work|show|church|school)\b", prev.lower()):
return True
if re.search(r"\b(wants|wanted|said|asked|bout|about|cause|cuz|bc|because|think|maybe|something|idk)\b", reply_lower):
if len(reply.split()) <= 10:
return True
if len(reply.split()) >= 3:
return False
return len(reply.split()) <= 2
if len(reply.split()) >= 4 and reply_toks:
ctx_toks = tokens(ctx + " " + user)
if reply_toks & ctx_toks:
return True
proper = re.findall(r"\b[A-Z][a-z]+(?:\s+[A-Z][a-z]+)+\b", reply)
for phrase in proper:
if phrase.lower() not in ctx:
return False
return True
except Exception:
return True