Merge pull request #12 from Kenearos/claude/init-irc-bot-dashboard-kYxih
Claude/init irc bot dashboard k yxih
This commit is contained in:
commit
952e543970
2 changed files with 133 additions and 15 deletions
56
chatbot.py
56
chatbot.py
|
|
@ -111,6 +111,62 @@ class EugenBot(irc.bot.SingleServerIRCBot):
|
||||||
self.handle_mention(username, message),
|
self.handle_mention(username, message),
|
||||||
self.loop
|
self.loop
|
||||||
)
|
)
|
||||||
|
# Check for ambiguous greetings (AI will decide if bot is addressed)
|
||||||
|
elif self.detector.is_ambiguous_greeting(message):
|
||||||
|
self.logger.debug(f"Ambiguous greeting detected from {username}: {message}")
|
||||||
|
if self.dashboard:
|
||||||
|
self.dashboard.log_event("info", {"message": f"Ambiguous greeting: {message}"})
|
||||||
|
|
||||||
|
# Ask AI if bot is addressed
|
||||||
|
asyncio.run_coroutine_threadsafe(
|
||||||
|
self.check_if_addressed(username, message),
|
||||||
|
self.loop
|
||||||
|
)
|
||||||
|
|
||||||
|
async def check_if_addressed(self, username, message):
|
||||||
|
"""
|
||||||
|
Check with AI if an ambiguous message is addressed to the bot
|
||||||
|
|
||||||
|
Args:
|
||||||
|
username (str): User who sent the message
|
||||||
|
message (str): Ambiguous message (e.g., "Hi wie gehts")
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Ask AI if the message is directed at the bot
|
||||||
|
check_prompt = f"""You are {self.bot_name}, a Twitch chat bot.
|
||||||
|
|
||||||
|
A user named {username} just wrote: "{message}"
|
||||||
|
|
||||||
|
This message doesn't explicitly mention you, but it might be directed at you.
|
||||||
|
Consider:
|
||||||
|
- Is this a greeting or question that could be for the bot?
|
||||||
|
- Is there recent conversation context suggesting it's for you?
|
||||||
|
- Or is it likely a general chat message not for the bot?
|
||||||
|
|
||||||
|
Respond with ONLY "YES" if the message is likely addressed to you, or "NO" if not.
|
||||||
|
Do not explain, just answer YES or NO."""
|
||||||
|
|
||||||
|
messages = [{"role": "user", "content": check_prompt}]
|
||||||
|
|
||||||
|
self.logger.debug(f"Asking AI if addressed: {message}")
|
||||||
|
response = await self.ai.get_response(messages)
|
||||||
|
|
||||||
|
if response and "YES" in response.upper():
|
||||||
|
self.logger.debug(f"AI says message is for bot: {message}")
|
||||||
|
if self.dashboard:
|
||||||
|
self.dashboard.log_event("info", {"message": f"AI confirmed: message is for bot"})
|
||||||
|
|
||||||
|
# Treat as mention and respond
|
||||||
|
await self.handle_mention(username, message)
|
||||||
|
else:
|
||||||
|
self.logger.debug(f"AI says message is not for bot: {message}")
|
||||||
|
if self.dashboard:
|
||||||
|
self.dashboard.log_event("info", {"message": f"AI confirmed: message is not for bot"})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Error checking if addressed: {str(e)}")
|
||||||
|
if self.dashboard:
|
||||||
|
self.dashboard.log_event("error", {"error": str(e)})
|
||||||
|
|
||||||
async def handle_mention(self, username, message):
|
async def handle_mention(self, username, message):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
92
utils.py
92
utils.py
|
|
@ -13,20 +13,53 @@ class MentionDetector:
|
||||||
|
|
||||||
def __init__(self, bot_name="Eugen"):
|
def __init__(self, bot_name="Eugen"):
|
||||||
self.bot_name = bot_name
|
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
|
# Create patterns for various mention formats
|
||||||
self.patterns = [
|
# Include bot name and all nicknames
|
||||||
rf"@{bot_name}", # @Eugen
|
all_names = [bot_name] + self.nicknames
|
||||||
rf"{bot_name}:", # Eugen:
|
self.patterns = []
|
||||||
rf"{bot_name},", # Eugen,
|
|
||||||
rf"^{bot_name}\s", # Eugen at start
|
for name in all_names:
|
||||||
rf"\s{bot_name}\s", # Eugen in middle
|
self.patterns.extend([
|
||||||
rf"\s{bot_name}$", # Eugen at end
|
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
|
# Case-insensitive compilation
|
||||||
self.compiled_patterns = [
|
self.compiled_patterns = [
|
||||||
re.compile(pattern, re.IGNORECASE) for pattern in self.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):
|
def is_mentioned(self, message):
|
||||||
"""
|
"""
|
||||||
Check if bot was mentioned in message
|
Check if bot was mentioned in message
|
||||||
|
|
@ -45,6 +78,28 @@ class MentionDetector:
|
||||||
return True
|
return True
|
||||||
return False
|
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):
|
def extract_content(self, message):
|
||||||
"""
|
"""
|
||||||
Extract message content without the mention
|
Extract message content without the mention
|
||||||
|
|
@ -58,15 +113,22 @@ class MentionDetector:
|
||||||
if not message:
|
if not message:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
# Remove common mention patterns
|
# Remove bot name and nickname mentions from the message
|
||||||
content = message
|
content = message
|
||||||
patterns_to_remove = [
|
all_names = [self.bot_name] + self.nicknames
|
||||||
rf"@{self.bot_name}[,:]?\s*",
|
|
||||||
rf"{self.bot_name}[,:]?\s*",
|
|
||||||
]
|
|
||||||
|
|
||||||
for pattern in patterns_to_remove:
|
for name in all_names:
|
||||||
content = re.sub(pattern, "", content, flags=re.IGNORECASE)
|
# Remove @mention at start
|
||||||
|
content = re.sub(rf"^@{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 name at end with optional punctuation
|
||||||
|
content = re.sub(rf"\s*\b{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()
|
return content.strip()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue