Add scoreboard roast feature via image analysis
When @mentioned with an image attachment, the bot now roasts players based on scoreboard screenshots using the vision model. Text-only mentions continue to work as before. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
76
cogs/chat.py
76
cogs/chat.py
@@ -9,6 +9,9 @@ logger = logging.getLogger("bcs.chat")
|
||||
|
||||
_PROMPTS_DIR = Path(__file__).resolve().parent.parent / "prompts"
|
||||
CHAT_PERSONALITY = (_PROMPTS_DIR / "chat_personality.txt").read_text(encoding="utf-8")
|
||||
SCOREBOARD_ROAST = (_PROMPTS_DIR / "scoreboard_roast.txt").read_text(encoding="utf-8")
|
||||
|
||||
_IMAGE_TYPES = {"png", "jpg", "jpeg", "gif", "webp"}
|
||||
|
||||
|
||||
class ChatCog(commands.Cog):
|
||||
@@ -54,21 +57,14 @@ class ChatCog(commands.Cog):
|
||||
|
||||
# Clean the mention out of the message content
|
||||
content = message.content.replace(f"<@{self.bot.user.id}>", "").strip()
|
||||
if not content:
|
||||
content = "(just pinged me)"
|
||||
|
||||
# Add drama score context to the user message
|
||||
drama_score = self.bot.drama_tracker.get_drama_score(message.author.id)
|
||||
user_data = self.bot.drama_tracker.get_user(message.author.id)
|
||||
score_context = (
|
||||
f"[Server context: {message.author.display_name} has a drama score of "
|
||||
f"{drama_score:.2f}/1.0 and {user_data.offense_count} offenses. "
|
||||
f"They are talking in #{message.channel.name}.]"
|
||||
)
|
||||
|
||||
self._chat_history[ch_id].append(
|
||||
{"role": "user", "content": f"{score_context}\n{message.author.display_name}: {content}"}
|
||||
)
|
||||
# Check for image attachments
|
||||
image_attachment = None
|
||||
for att in message.attachments:
|
||||
ext = att.filename.rsplit(".", 1)[-1].lower() if "." in att.filename else ""
|
||||
if ext in _IMAGE_TYPES:
|
||||
image_attachment = att
|
||||
break
|
||||
|
||||
typing_ctx = None
|
||||
|
||||
@@ -77,11 +73,46 @@ class ChatCog(commands.Cog):
|
||||
typing_ctx = message.channel.typing()
|
||||
await typing_ctx.__aenter__()
|
||||
|
||||
response = await self.bot.llm.chat(
|
||||
list(self._chat_history[ch_id]),
|
||||
CHAT_PERSONALITY,
|
||||
on_first_token=start_typing,
|
||||
)
|
||||
if image_attachment:
|
||||
# --- Image path: scoreboard roast ---
|
||||
image_bytes = await image_attachment.read()
|
||||
user_text = content if content else "Roast this scoreboard."
|
||||
logger.info(
|
||||
"Image roast request in #%s from %s (%s, %s)",
|
||||
message.channel.name,
|
||||
message.author.display_name,
|
||||
image_attachment.filename,
|
||||
user_text[:80],
|
||||
)
|
||||
response = await self.bot.llm.analyze_image(
|
||||
image_bytes,
|
||||
SCOREBOARD_ROAST,
|
||||
user_text=user_text,
|
||||
on_first_token=start_typing,
|
||||
)
|
||||
else:
|
||||
# --- Text-only path: normal chat ---
|
||||
if not content:
|
||||
content = "(just pinged me)"
|
||||
|
||||
# Add drama score context to the user message
|
||||
drama_score = self.bot.drama_tracker.get_drama_score(message.author.id)
|
||||
user_data = self.bot.drama_tracker.get_user(message.author.id)
|
||||
score_context = (
|
||||
f"[Server context: {message.author.display_name} has a drama score of "
|
||||
f"{drama_score:.2f}/1.0 and {user_data.offense_count} offenses. "
|
||||
f"They are talking in #{message.channel.name}.]"
|
||||
)
|
||||
|
||||
self._chat_history[ch_id].append(
|
||||
{"role": "user", "content": f"{score_context}\n{message.author.display_name}: {content}"}
|
||||
)
|
||||
|
||||
response = await self.bot.llm.chat(
|
||||
list(self._chat_history[ch_id]),
|
||||
CHAT_PERSONALITY,
|
||||
on_first_token=start_typing,
|
||||
)
|
||||
|
||||
if typing_ctx:
|
||||
await typing_ctx.__aexit__(None, None, None)
|
||||
@@ -89,9 +120,10 @@ class ChatCog(commands.Cog):
|
||||
if response is None:
|
||||
response = "I'd roast you but my brain is offline. Try again later."
|
||||
|
||||
self._chat_history[ch_id].append(
|
||||
{"role": "assistant", "content": response}
|
||||
)
|
||||
if not image_attachment:
|
||||
self._chat_history[ch_id].append(
|
||||
{"role": "assistant", "content": response}
|
||||
)
|
||||
|
||||
await message.reply(response, mention_author=False)
|
||||
logger.info(
|
||||
|
||||
Reference in New Issue
Block a user