fix: gpt-oss:20b ollama, streaming, tableaux JSON, recherche flexible salons/categories
This commit is contained in:
parent
14985f6dbb
commit
189d56026b
21 changed files with 2824 additions and 491 deletions
|
|
@ -1,4 +1,15 @@
|
|||
def _assess_heuristic_risk(self, message) -> bool:
|
||||
import logging
|
||||
import re
|
||||
|
||||
logger = logging.getLogger('Superviseur')
|
||||
|
||||
class HeuristicsManager:
|
||||
"""Handles parsing and computing heuristic risk scores for messages."""
|
||||
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
def assess_risk(self, message) -> bool:
|
||||
"""
|
||||
Fast Python-side risk assessment to decide if we should AI-analyze fully.
|
||||
Returns True if message is 'risky' enough to warrant LLM usage.
|
||||
|
|
@ -6,41 +17,92 @@
|
|||
score = 0
|
||||
content = message.content
|
||||
|
||||
# 1. Social Score Factor (Base scrutiny)
|
||||
# If user is Suspect (<40), we start with higher risk score
|
||||
social_data = self.social_manager.get_user_data(message.author.id)
|
||||
reliability = social_data.get('score', 50)
|
||||
# CLEAN content for heuristic analysis (ignore mentions in the score)
|
||||
# We use a copy to avoid modifying the original message object
|
||||
scoring_content = re.sub(r'<@!?\d+>', '', content).strip()
|
||||
if not scoring_content: scoring_content = content
|
||||
|
||||
if reliability < 30: score += 40 # Very suspicious user -> almost auto-check
|
||||
elif reliability < 50: score += 20
|
||||
# 1. Content Scoring
|
||||
score = 0
|
||||
|
||||
# 2. Pattern Matching (Fast Regex/Keywords)
|
||||
content_lower = content.lower()
|
||||
|
||||
# CAPS LOCK detection (> 60% caps on long messages)
|
||||
# Proactive Analysis: base score if message has substance
|
||||
if len(content) > 10:
|
||||
caps_ratio = sum(1 for c in content if c.isupper()) / len(content)
|
||||
if caps_ratio > 0.6: score += 30
|
||||
score += 15
|
||||
|
||||
scoring_content = content
|
||||
scoring_content_lower = scoring_content.lower()
|
||||
|
||||
# CAPS LOCK detection (> 35% caps on messages > 4 chars)
|
||||
if len(scoring_content) > 4:
|
||||
caps_ratio = sum(1 for c in scoring_content if c.isupper()) / len(scoring_content)
|
||||
if caps_ratio > 0.35:
|
||||
score += 35 # Heavy weight
|
||||
logger.debug(f"◈ HEURISTIC: CAPS detected ({caps_ratio:.2f}) on '{scoring_content[:15]}...'")
|
||||
|
||||
# Profanity / Trigger words (lightweight list)
|
||||
triggers = ["raid", "hack", "pute", "connard", "fdp", "tg", "merde", "nazi", "hitler", "suicide", "bomb", "token", "grab", "nitro", "steam", "discord.gift", "free", "@everyone", "@here"]
|
||||
triggers = [
|
||||
"raid", "hack", "pute", "connard", "fdp", "tg", "merde", "nazi", "hitler",
|
||||
"suicide", "bomb", "token", "grab", "nitro", "steam", "discord.gift", "free",
|
||||
"@everyone", "@here", "detruire", "detruit", "destruction", "kill"
|
||||
]
|
||||
for t in triggers:
|
||||
if t in content_lower:
|
||||
if t in scoring_content_lower:
|
||||
score += 50
|
||||
logger.debug(f"◈ HEURISTIC: Trigger word '{t}' detected")
|
||||
break
|
||||
|
||||
# Link spam detection
|
||||
if "http" in content_lower:
|
||||
score += 15
|
||||
|
||||
# Length anomaly (very long messages often rants)
|
||||
if len(content) > 400:
|
||||
if "http" in scoring_content_lower:
|
||||
score += 20
|
||||
|
||||
# 3. Mention Spam
|
||||
if len(message.mentions) > 3:
|
||||
score += 40
|
||||
# Length anomaly
|
||||
if len(scoring_content) > 300:
|
||||
score += 20
|
||||
|
||||
# 3. Gibberish / Randomness detection (Entropy)
|
||||
if len(scoring_content) > 8:
|
||||
unique_chars = len(set(scoring_content_lower))
|
||||
diversity_ratio = unique_chars / len(scoring_content)
|
||||
if diversity_ratio < 0.35: # Increased threshold
|
||||
score += 25
|
||||
logger.debug(f"◈ HEURISTIC: Low diversity detected ({diversity_ratio:.2f})")
|
||||
|
||||
# Too many non-alphanumeric chars (excluding spaces)
|
||||
symbols = len(re.findall(r'[^a-zA-Z0-9\s]', scoring_content))
|
||||
symbol_ratio = symbols / len(scoring_content)
|
||||
if symbol_ratio > 0.15: # Lowered threshold for symbols
|
||||
score += 30
|
||||
logger.debug(f"◈ HEURISTIC: High symbol ratio detected ({symbol_ratio:.2f})")
|
||||
|
||||
# 4. Leetspeak / Digits in words detection
|
||||
if len(re.findall(r'[a-zA-Z][0-9][a-zA-Z]', scoring_content)) > 0:
|
||||
score += 25
|
||||
logger.debug("◈ HEURISTIC: Leetspeak patterns detected")
|
||||
|
||||
# 5. Long word detection (No spaces)
|
||||
words = scoring_content.split()
|
||||
if any(len(w) > 25 for w in words):
|
||||
score += 30
|
||||
logger.debug("◈ HEURISTIC: Unusually long word detected")
|
||||
|
||||
# 3. Mention Spam
|
||||
# Fallback detection if library fails to populate message.mentions
|
||||
mention_count = len(message.mentions)
|
||||
if mention_count == 0:
|
||||
mention_count = len(re.findall(r'<@!?\d+>', content))
|
||||
|
||||
if mention_count > 3:
|
||||
score += 40
|
||||
logger.debug(f"◈ HEURISTIC: Mention spam detected ({mention_count} mentions)")
|
||||
|
||||
# 4. Keyword Detection (Sensitivity helper)
|
||||
if score < 45:
|
||||
for trigger in ["analyse", "écouter", "surveille", "check"]:
|
||||
if trigger in scoring_content_lower:
|
||||
score += 30
|
||||
break
|
||||
|
||||
# Threshold decision
|
||||
# If score > 45, we analyze.
|
||||
return score >= 45
|
||||
# Very sensitive threshold to capture more nuances (as requested)
|
||||
logger.info(f"◈ MODERATION RISK: Score Final = {score}/15")
|
||||
return score >= 15
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue