From f0c00296a1223f7b78337f4b34f12b80b1d7a154 Mon Sep 17 00:00:00 2001 From: Codex Date: Sat, 7 Jun 2025 17:44:05 +0000 Subject: [PATCH] Enhance appeal context in logs and tests --- cogs/aimod_cog.py | 75 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/cogs/aimod_cog.py b/cogs/aimod_cog.py index c754233..8db54f2 100644 --- a/cogs/aimod_cog.py +++ b/cogs/aimod_cog.py @@ -1066,6 +1066,27 @@ class AIModerationCog(commands.Cog): embed.add_field(name="Action", value=action, inline=False) if ref: embed.add_field(name="Infraction", value=f"Message ID: {ref}", inline=False) + msg_snip = ( + target_infraction.get("message_content") if target_infraction else None + ) + if msg_snip: + embed.add_field( + name="Message Snippet", + value=f"`{msg_snip}`", + inline=False, + ) + attachments = ( + target_infraction.get("attachments") if target_infraction else None + ) + if attachments: + attach_text = "\n".join(attachments) + if len(attach_text) > 1024: + attach_text = attach_text[:1021] + "..." + embed.add_field( + name="Attachments", + value=attach_text, + inline=False, + ) embed.add_field(name="Appeal", value=reason, inline=False) embed.add_field(name="AI Review", value=ai_review[:1000], inline=False) embed.timestamp = discord.utils.utcnow() @@ -1095,6 +1116,7 @@ class AIModerationCog(commands.Cog): return appeals = get_user_appeals(interaction.guild.id, user.id) + history = get_user_infraction_history(interaction.guild.id, user.id) if not appeals: await interaction.response.send_message( f"{user.mention} has no appeals.", ephemeral=False @@ -1116,6 +1138,23 @@ class AIModerationCog(commands.Cog): ref = appeal.get("infraction_reference") if ref: value = f"Infraction: {ref}\n" + value + for infr in history: + if str(infr.get("message_id")) == str(ref): + msg_snip = infr.get("message_content") + if msg_snip: + value += f"\nSnippet: {msg_snip}" + attachments = infr.get("attachments") + if attachments: + attach_txt = ", ".join(attachments) + if len(attach_txt) > 200: + attach_txt = attach_txt[:197] + "..." + value += f"\nAttachments: {attach_txt}" + reason = infr.get("reasoning") + if reason: + if len(reason) > 150: + reason = reason[:147] + "..." + value += f"\nAI Reasoning: {reason}" + break embed.add_field(name=f"Appeal #{i} - {ts}", value=value, inline=False) await interaction.response.send_message(embed=embed, ephemeral=False) @@ -1124,7 +1163,7 @@ class AIModerationCog(commands.Cog): description="Run sample appeals through the AI review system (admin only).", ) async def appeal_testcases(self, interaction: discord.Interaction): - """Run a few hardcoded appeal scenarios through the AI.""" + """Run a few hardcoded appeal scenarios through the AI with context.""" if not interaction.user.guild_permissions.administrator: await interaction.response.send_message( "You must be an administrator to use this command.", @@ -1135,20 +1174,21 @@ class AIModerationCog(commands.Cog): await interaction.response.defer(thinking=True, ephemeral=True) scenarios = [ - ("Warn for spam", "I got excited and posted too many messages."), - ( - "Mute for harassment", - "I was only teasing my friend and didn't mean to harass anyone.", - ), - ( - "Ban for posting slurs", - "I'm sorry for what I said and promise it will not happen again.", - ), + ("WARN", "I was excited and sent many messages quickly."), + ("MUTE", "I only quoted a meme and it was taken as harassment."), + ("BAN", "I posted NSFW art but believed it was allowed."), ] results: list[tuple[str, str]] = [] - for action, text in scenarios: + for idx, (action, text) in enumerate(scenarios, 1): + dummy_infraction = { + "message_id": 1000 + idx, + "channel_id": interaction.channel.id, + "message_content": f"Example offending message {idx}", + "attachments": [], + "reasoning": "Automated moderation reasoning sample", + } result = await self.run_appeal_ai( - interaction.guild, interaction.user, action, text, None + interaction.guild, interaction.user, action, text, dummy_infraction ) results.append((action, result)) @@ -2794,9 +2834,16 @@ CRITICAL: Do NOT output anything other than the required JSON response. results = [] guild = interaction.guild - for action, text in scenarios: + for idx, (action, text) in enumerate(scenarios, 1): + dummy_infraction = { + "message_id": 2000 + idx, + "channel_id": interaction.channel.id, + "message_content": f"Test offending message {idx}", + "attachments": [], + "reasoning": "Initial moderation reasoning sample", + } review = await self.run_appeal_ai( - guild, interaction.user, action, text, None + guild, interaction.user, action, text, dummy_infraction ) results.append((action, text, review))