diff --git a/cogs/socials.py b/cogs/socials.py index 17de966..1cdcbc4 100644 --- a/cogs/socials.py +++ b/cogs/socials.py @@ -7,6 +7,7 @@ import assets import utils +from utils import build_input_history class Socials(discord.Cog, name="Socials"): @@ -234,38 +235,7 @@ async def gay(self, ctx, user=None, border=False, server_avatar=True): async def gpt(self, ctx: discord.ApplicationContext, text: str): """ Talk to Paw! """ await ctx.defer() - messages = await ctx.channel.history(limit=50).flatten() - messages.reverse() - input_history = [{"role": "system", "content": utils.SYSTEM_PROMPT}] - alt_text = None - for message in messages: - if message.author != self.bot.user: - if message.attachments and message.attachments[0].content_type.startswith("image"): - alt_text = f"\nThe user attached an image to the message: {await utils.analyse_image(message.attachments[0].url)}" - if message.content is None or message.content == "": - input_history.append( - {"role": "user", "name": message.author.display_name, - "content": f"{message.author.display_name} ({utils.get_gender(message.author)}) sent a file. {alt_text}"}) - else: - input_history.append( - {"role": "user", "name": message.author.display_name, - "content": f"{message.author.display_name} ({utils.get_gender(message.author)}) said: {message.content} {alt_text}"}) - continue - try: - usermessage = message.content.split("\n")[0] # Get the first line of the message. the user prompt - botmsg = message.content.split("\n")[1] # Second line, Paw's response - except IndexError: - input_history.append({"role": "assistant", "content": message.content}) - continue - if not usermessage.startswith("**Prompt:**") and not botmsg.startswith("**Paw:**"): - continue - input_history.append( - {"role": "user", "name": ctx.guild.get_member(message.interaction_metadata.user.id).display_name, - "content": f"{ctx.guild.get_member(message.interaction_metadata.user.id).display_name} ({utils.get_gender(ctx.guild.get_member(message.interaction_metadata.user.id))}) said: {usermessage[12:]} {alt_text}"}) - input_history.append({"role": "assistant", "content": botmsg[9:]}) - input_history.append( - {"role": "user", "name": ctx.author.display_name, - "content": f"{ctx.author.display_name} ({utils.get_gender(ctx.author)}) said: {text}"}) + input_history = await build_input_history(self.bot, ctx, text) response = await utils.generate_from_history(input_history) await ctx.respond(content=f"**Prompt:** {text}\n**Paw:** {response}") diff --git a/utils/socials_helpers.py b/utils/socials_helpers.py index 42cd36d..a4f5892 100644 --- a/utils/socials_helpers.py +++ b/utils/socials_helpers.py @@ -2,6 +2,7 @@ import discord +import utils from views import InteractionsView @@ -62,3 +63,67 @@ async def social_interaction_handler(ctx: discord.ApplicationContext, members: l embed = await interactions(ctx, memberlist, words[0], gifs) view = InteractionsView(ctx, memberlist, words[0], words[1], gifs, words[2] if len(words) > 2 else None) await ctx.respond(embed=embed, view=view) + + +def format_current_user_message(author: discord.Member, text: str) -> dict: + return { + "role": "user", + "name": author.display_name, + "content": f"{author.display_name} ({utils.get_gender(author)}) said: {text}" + } + + +def format_bot_message(message: discord.Message, guild: discord.Guild) -> list: + try: + user_prompt, bot_response = message.content.split("\n", 1) + except ValueError: + return [{"role": "assistant", "content": message.content}] + + if not user_prompt.startswith("**Prompt:**") or not bot_response.startswith("**Paw:**"): + return [] + + user = guild.get_member(message.interaction_metadata.user.id) + return [ + { + "role": "user", + "name": user.display_name, + "content": f"{user.display_name} ({utils.get_gender(user)}) said: {user_prompt[12:]}" + }, + {"role": "assistant", "content": bot_response[9:]} + ] + + +async def get_image_alt_text(message: discord.Message) -> str: + if message.attachments and message.attachments[0].content_type.startswith("image"): + return f"\nThe user attached an image to the message: {await utils.analyse_image(message.attachments[0].url)}" + return "" + + +async def format_user_message(message: discord.Message) -> dict: + alt_text = await get_image_alt_text(message) + content = message.content if message.content else f"{message.author.display_name} sent a file." + return { + "role": "user", + "name": message.author.display_name, + "content": f"{message.author.display_name} ({utils.get_gender(message.author)}) said: {content} {alt_text}" + } + + +async def get_channel_history(channel) -> list[discord.Message]: + messages = await channel.history(limit=50).flatten() + messages.reverse() + return messages + + +async def build_input_history(bot, ctx: discord.ApplicationContext, prompt: str) -> list: + messages = await get_channel_history(ctx.channel) + input_history = [{"role": "system", "content": utils.SYSTEM_PROMPT}] + + for message in messages: + if message.author != bot.user: + input_history.append(await format_user_message(message)) + else: + input_history.extend(format_bot_message(message, ctx.guild)) + + input_history.append(format_current_user_message(ctx.author, prompt)) + return input_history