From f6908215994f5bd5fb2dae4cf6901f5f68c43b0c Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 08:59:32 +0000 Subject: [PATCH 1/8] Replace user mentions with the nickname in prompt and output --- cogs/gpt_3_commands_and_converser.py | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 7eb4b4b..5d1d57e 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -594,6 +594,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): # ":" message, create a new : section with the new prompt, and then set the prompt to # the new prompt, then send that new prompt as the new prompt. if after.channel.id in self.conversation_threads: + edited_content = await self.replace_mention(after, edited_content) # Remove the last two elements from the history array and add the new : prompt self.conversation_threads[ after.channel.id @@ -657,7 +658,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): if not user_api_key: return - prompt = content + prompt = await self.replace_mention(message, content) await self.check_conversation_limit(message) @@ -741,6 +742,16 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_text = response_text.replace("<|endofstatement|>", "") return response_text + async def replace_mention(self, ctx, message): + if discord.utils.raw_mentions(message): + for mention in discord.utils.raw_mentions(message): + user = await discord.utils.get_or_fetch(ctx.guild, 'member', mention, default="User") + display_name = user.display_name + message = message.replace(f"<@{str(mention)}>", display_name) + return message + else: + return message + # ctx can be of type AppContext(interaction) or Message async def encapsulated_send( self, @@ -926,11 +937,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_text = f"***{prompt}***\n\n{response_text}" # If GPT3 tries to ping somebody, don't let it happen - if re.search(r"<@!?\d+>|<@&\d+>|<#\d+>", str(response_text)): - message = "I'm sorry, I can't mention users, roles, or channels." - await ctx.send_followup(message) if from_context else await ctx.reply( - message - ) + response_text = await self.replace_mention(ctx, response_text) # If the user is conversing, add the GPT response to their conversation history. if ( @@ -1111,7 +1118,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): presence_penalty: float, ): user = ctx.user - prompt = prompt.strip() + prompt = await self.replace_mention(ctx, prompt.strip()) # If the prompt isn't empty and the last character isn't a punctuation character, add a period. if prompt and prompt[-1] not in [".", "!", "?"]: @@ -1200,6 +1207,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): ) return + if opener: + opener = await self.replace_mention(ctx, opener) + if not opener and not opener_file: user_id_normalized = user.id else: From e6bba27761e8bd85842821aa0d5a28589a40757d Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 10:06:18 +0000 Subject: [PATCH 2/8] edit on_message_edit --- cogs/gpt_3_commands_and_converser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 5d1d57e..9ce8748 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -589,12 +589,11 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): ctx = self.redo_users[after.author.id].ctx await response_message.edit(content="Redoing prompt 🔄...") - edited_content = after.content + edited_content = await self.replace_mention(after, after.content) # If the user is conversing, we need to get their conversation history, delete the last # ":" message, create a new : section with the new prompt, and then set the prompt to # the new prompt, then send that new prompt as the new prompt. if after.channel.id in self.conversation_threads: - edited_content = await self.replace_mention(after, edited_content) # Remove the last two elements from the history array and add the new : prompt self.conversation_threads[ after.channel.id From d93a1db51f43be0fd96172ac7411c000eb338b47 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 10:15:37 +0000 Subject: [PATCH 3/8] Shorten the replace function --- cogs/gpt_3_commands_and_converser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 9ce8748..6cc4c77 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -745,8 +745,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): if discord.utils.raw_mentions(message): for mention in discord.utils.raw_mentions(message): user = await discord.utils.get_or_fetch(ctx.guild, 'member', mention, default="User") - display_name = user.display_name - message = message.replace(f"<@{str(mention)}>", display_name) + message = message.replace(f"<@{str(mention)}>", user.display_name) return message else: return message From a46528ba90bd0d346c5ddd278881d0cbf87cde67 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 10:27:08 +0000 Subject: [PATCH 4/8] Add escape on mentions --- cogs/gpt_3_commands_and_converser.py | 2 ++ cogs/image_prompt_optimizer.py | 8 ++------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 6cc4c77..c1f1277 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -936,6 +936,8 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): # If GPT3 tries to ping somebody, don't let it happen response_text = await self.replace_mention(ctx, response_text) + # escape any other metnions + response_text = discord.utils.escape_mentions(response_text) # If the user is conversing, add the GPT response to their conversation history. if ( diff --git a/cogs/image_prompt_optimizer.py b/cogs/image_prompt_optimizer.py index ffd1e99..0a08add 100644 --- a/cogs/image_prompt_optimizer.py +++ b/cogs/image_prompt_optimizer.py @@ -74,7 +74,7 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"): user = ctx.user final_prompt = self.OPTIMIZER_PRETEXT - final_prompt += prompt + final_prompt += await self.converser_cog.replace_mention(ctx, prompt) # If the prompt doesn't end in a period, terminate it. if not final_prompt.endswith("."): @@ -101,11 +101,7 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"): response_text = response["choices"][0]["text"] - if re.search(r"<@!?\d+>|<@&\d+>|<#\d+>", response_text): - await ctx.respond( - "I'm sorry, I can't mention users, roles, or channels." - ) - return + response_text = discord.utils.escape_mentions(response_text) response_message = await ctx.respond( response_text.replace("Optimized Prompt:", "") From cff7d09013d441a0961e4a09f18b2f3918022e05 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 11:53:30 +0000 Subject: [PATCH 5/8] Fix mention escaping in conversations due to non-ascii removal --- cogs/gpt_3_commands_and_converser.py | 9 +++++---- cogs/image_prompt_optimizer.py | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index c1f1277..36faba0 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -934,10 +934,8 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_text = response_text.strip() response_text = f"***{prompt}***\n\n{response_text}" - # If GPT3 tries to ping somebody, don't let it happen + # If gpt3 tries writing a user mention try to replace it with their name response_text = await self.replace_mention(ctx, response_text) - # escape any other metnions - response_text = discord.utils.escape_mentions(response_text) # If the user is conversing, add the GPT response to their conversation history. if ( @@ -981,9 +979,12 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): custom_api_key=custom_api_key, ) - # Cleanse + # Cleanse again response_text = self.cleanse_response(response_text) + # escape any other mentions like @here or @everyone + response_text = discord.utils.escape_mentions(response_text) + # If we don't have a response message, we are not doing a redo, send as a new message(s) if not response_message: if len(response_text) > self.TEXT_CUTOFF: diff --git a/cogs/image_prompt_optimizer.py b/cogs/image_prompt_optimizer.py index 0a08add..47ab95d 100644 --- a/cogs/image_prompt_optimizer.py +++ b/cogs/image_prompt_optimizer.py @@ -74,6 +74,7 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"): user = ctx.user final_prompt = self.OPTIMIZER_PRETEXT + # replace mentions with nicknames for the prompt final_prompt += await self.converser_cog.replace_mention(ctx, prompt) # If the prompt doesn't end in a period, terminate it. @@ -100,7 +101,7 @@ class ImgPromptOptimizer(discord.Cog, name="ImgPromptOptimizer"): # also relatively cost-effective response_text = response["choices"][0]["text"] - + # escape any mentions response_text = discord.utils.escape_mentions(response_text) response_message = await ctx.respond( From 67546d0705976e0a9332ec36ee857bbde1cfacaa Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 12:27:42 +0000 Subject: [PATCH 6/8] Cleanup after merge --- cogs/gpt_3_commands_and_converser.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 4272c16..a3c1086 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -622,9 +622,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): await response_message.edit(content="Redoing prompt 🔄...") edited_content = await self.replace_mention(after, after.content) - # If the user is conversing, we need to get their conversation history, delete the last - # ":" message, create a new : section with the new prompt, and then set the prompt to - # the new prompt, then send that new prompt as the new prompt. + if after.channel.id in self.conversation_threads: # Remove the last two elements from the history array and add the new : prompt self.conversation_threads[ From 5504ea28026280308bcd35a2adc4d28d8a1f6573 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 12:49:07 +0000 Subject: [PATCH 7/8] Fix cases where the user doesn't exist in the guild Extra: add sqlite files to gitignore --- .gitignore | 1 + cogs/gpt_3_commands_and_converser.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 4244f47..a95b25f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ __pycache__ #user files .env .vscode +*.sqlite bot.pid usage.txt /dalleimages \ No newline at end of file diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index a3c1086..4f0d3b7 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -790,10 +790,14 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): async def replace_mention(self, ctx, message): if discord.utils.raw_mentions(message): - for mention in discord.utils.raw_mentions(message): - user = await discord.utils.get_or_fetch(ctx.guild, 'member', mention, default="User") - message = message.replace(f"<@{str(mention)}>", user.display_name) - return message + for mention in discord.utils.raw_mentions(message): + try: + user = await discord.utils.get_or_fetch(ctx.guild, 'member', mention) + username = user.display_name + except: + username = str(mention) + message = message.replace(f"<@{str(mention)}>", username) + return message else: return message From 07849ca42ea08eeadfb4dd6d9d30f51ed99a13b8 Mon Sep 17 00:00:00 2001 From: Rene Teigen Date: Wed, 11 Jan 2023 13:43:49 +0000 Subject: [PATCH 8/8] Slight refactor --- cogs/gpt_3_commands_and_converser.py | 31 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/cogs/gpt_3_commands_and_converser.py b/cogs/gpt_3_commands_and_converser.py index 4f0d3b7..c1822ef 100644 --- a/cogs/gpt_3_commands_and_converser.py +++ b/cogs/gpt_3_commands_and_converser.py @@ -621,7 +621,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): ctx = self.redo_users[after.author.id].ctx await response_message.edit(content="Redoing prompt 🔄...") - edited_content = await self.replace_mention(after, after.content) + edited_content = await self.mention_to_username(after, after.content) if after.channel.id in self.conversation_threads: # Remove the last two elements from the history array and add the new : prompt @@ -706,7 +706,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): if not user_api_key: return - prompt = await self.replace_mention(message, content) + prompt = await self.mention_to_username(message, content) await self.check_conversation_limit(message) @@ -788,18 +788,17 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_text = response_text.replace("<|endofstatement|>", "") return response_text - async def replace_mention(self, ctx, message): - if discord.utils.raw_mentions(message): - for mention in discord.utils.raw_mentions(message): - try: - user = await discord.utils.get_or_fetch(ctx.guild, 'member', mention) - username = user.display_name - except: - username = str(mention) - message = message.replace(f"<@{str(mention)}>", username) - return message - else: + async def mention_to_username(self, ctx, message): + if not discord.utils.raw_mentions(message): return message + else: + for mention in discord.utils.raw_mentions(message): + try: + user = await discord.utils.get_or_fetch(ctx.guild, 'member', mention) + message = message.replace(f"<@{str(mention)}>", user.display_name) + except: + pass + return message # ctx can be of type AppContext(interaction) or Message async def encapsulated_send( @@ -983,7 +982,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): response_text = f"***{prompt}***\n\n{response_text}" # If gpt3 tries writing a user mention try to replace it with their name - response_text = await self.replace_mention(ctx, response_text) + response_text = await self.mention_to_username(ctx, response_text) # If the user is conversing, add the GPT response to their conversation history. if ( @@ -1167,7 +1166,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): presence_penalty: float, ): user = ctx.user - prompt = await self.replace_mention(ctx, prompt.strip()) + prompt = await self.mention_to_username(ctx, prompt.strip()) user_api_key = None if USER_INPUT_API_KEYS: @@ -1249,7 +1248,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"): return if opener: - opener = await self.replace_mention(ctx, opener) + opener = await self.mention_to_username(ctx, opener) if not opener and not opener_file: user_id_normalized = user.id