Add nickname detection and AI-based ambiguous message handling

Enhanced bot to respond to partial names and ambiguous greetings:

MentionDetector improvements (utils.py):
- Auto-generate nicknames from bot name (kenearosmd → Kene, Kenearos)
- Add patterns for all nicknames (full name + partial names)
- New is_ambiguous_greeting() method for greetings without clear mention
- Updated extract_content() to remove all name variants

Bot logic improvements (chatbot.py):
- New check_if_addressed() method uses AI to determine if ambiguous
  messages are directed at the bot
- AI analyzes greetings like "Hi wie gehts" and decides if bot should respond
- If AI confirms, message is processed like a normal mention

Recognition examples:
- kenearosmd: wie gehts → responds 
- Kene was meinst du → responds 
- Kenearos! → responds 
- Hi wie gehts → AI checks context → responds if appropriate 

This prevents the bot from spamming on every greeting while still
being responsive when addressed indirectly.
This commit is contained in:
Claude 2026-01-02 21:30:20 +00:00
parent 0b2d166a58
commit 5e0ebbb1c4
No known key found for this signature in database
2 changed files with 130 additions and 16 deletions

View file

@ -13,19 +13,53 @@ class MentionDetector:
def __init__(self, bot_name="Eugen"):
self.bot_name = bot_name
# Generate nicknames/partial names from bot_name
self.nicknames = self._generate_nicknames(bot_name)
# Create patterns for various mention formats
# More flexible patterns that catch most cases
self.patterns = [
rf"@{bot_name}\b", # @Eugen (with word boundary)
rf"\b{bot_name}[:!?.,]", # Eugen: Eugen! Eugen? Eugen, Eugen.
rf"^{bot_name}\b", # Eugen at start of message
rf"\b{bot_name}\b", # Eugen anywhere as whole word
]
# Include bot name and all nicknames
all_names = [bot_name] + self.nicknames
self.patterns = []
for name in all_names:
self.patterns.extend([
rf"@{name}\b", # @name (with word boundary)
rf"\b{name}[:!?.,]", # name: name! name? name, name.
rf"^{name}\b", # name at start of message
rf"\b{name}\b", # name anywhere as whole word
])
# Case-insensitive compilation
self.compiled_patterns = [
re.compile(pattern, re.IGNORECASE) for pattern in self.patterns
]
# Patterns for ambiguous greetings (might be directed at bot)
self.greeting_patterns = [
r"^(hi|hey|hallo|hello|servus|moin)(\s|$|\W)",
r"^(wie\s+geht'?s|wie\s+gehts|how\s+are\s+you)",
r"^(alles\s+klar|everything\s+ok)",
]
self.compiled_greetings = [
re.compile(pattern, re.IGNORECASE) for pattern in self.greeting_patterns
]
def _generate_nicknames(self, bot_name):
"""Generate common nicknames from bot name"""
nicknames = []
# For kenearosmd, generate: Kene, Kenearos
if len(bot_name) >= 4:
nicknames.append(bot_name[:4]) # First 4 chars (Kene)
if len(bot_name) >= 8:
nicknames.append(bot_name[:8]) # First 8 chars (Kenearos)
# Remove duplicates and the full name
nicknames = [n for n in set(nicknames) if n != bot_name]
return nicknames
def is_mentioned(self, message):
"""
Check if bot was mentioned in message
@ -44,6 +78,28 @@ class MentionDetector:
return True
return False
def is_ambiguous_greeting(self, message):
"""
Check if message is an ambiguous greeting that might be for the bot
Args:
message (str): Chat message to check
Returns:
bool: True if message is an ambiguous greeting
"""
if not message:
return False
# Don't check if there's already a clear mention
if self.is_mentioned(message):
return False
for pattern in self.compiled_greetings:
if pattern.search(message):
return True
return False
def extract_content(self, message):
"""
Extract message content without the mention
@ -57,20 +113,22 @@ class MentionDetector:
if not message:
return ""
# Remove bot name mentions from the message
# Remove bot name and nickname mentions from the message
content = message
all_names = [self.bot_name] + self.nicknames
# Remove @mention at start
content = re.sub(rf"^@{self.bot_name}\b[,:]?\s*", "", content, flags=re.IGNORECASE)
for name in all_names:
# Remove @mention at start
content = re.sub(rf"^@{name}\b[,:]?\s*", "", content, flags=re.IGNORECASE)
# Remove bot name at start with optional punctuation
content = re.sub(rf"^{self.bot_name}\b[,:]?\s*", "", content, flags=re.IGNORECASE)
# Remove name at start with optional punctuation
content = re.sub(rf"^{name}\b[,:]?\s*", "", content, flags=re.IGNORECASE)
# Remove bot name at end with optional punctuation
content = re.sub(rf"\s*\b{self.bot_name}[,!?.]?\s*$", "", content, flags=re.IGNORECASE)
# Remove name at end with optional punctuation
content = re.sub(rf"\s*\b{name}[,!?.]?\s*$", "", content, flags=re.IGNORECASE)
# Remove bot name in middle with punctuation
content = re.sub(rf"\s*\b{self.bot_name}[,:!?]\s*", " ", content, flags=re.IGNORECASE)
# Remove name in middle with punctuation
content = re.sub(rf"\s*\b{name}[,:!?]\s*", " ", content, flags=re.IGNORECASE)
return content.strip()