Merge pull request #112 from Hikari-Haru/formatting-and-fixes

Add stop in conversation, some formatting
Kaveen Kumarasinghe 1 year ago committed by GitHub
commit 3337753e9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -128,8 +128,8 @@ class ModerationsService(discord.Cog, name="ModerationsService"):
Moderation.moderation_tasks[guild_id] = asyncio.ensure_future(
Moderation.process_moderation_queue(
Moderation.moderation_queues[guild_id],
1,
1,
0.25,
0.25,
moderations_channel,
warn_set,
delete_set,

@ -511,9 +511,9 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
after.guild.id in Moderation.moderation_queues
and Moderation.moderation_queues[after.guild.id] is not None
):
# Create a timestamp that is 0.5 seconds from now
# Create a timestamp that is 0.25 seconds from now
timestamp = (
datetime.datetime.now() + datetime.timedelta(seconds=0.5)
datetime.datetime.now() + datetime.timedelta(seconds=0.25)
).timestamp()
await Moderation.moderation_queues[after.guild.id].put(
Moderation(after, timestamp)
@ -533,8 +533,11 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
and message.guild.id in Moderation.moderation_queues
and Moderation.moderation_queues[message.guild.id] is not None
):
# Don't moderate if there is no "roles" attribute for the author
if not hasattr(message.author, "roles"):
pass
# Verify that the user is not in a role that can bypass moderation
if CHAT_BYPASS_ROLES is [None] or not any(
elif CHAT_BYPASS_ROLES is [None] or not any(
role.name.lower() in CHAT_BYPASS_ROLES for role in message.author.roles
):
# Create a timestamp that is 0.5 seconds from now
@ -841,7 +844,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
elif not private:
message_thread = await ctx.respond(
embed=discord.Embed(
title=f"{user.name} 's conversation with GPT3", color=0x808080
title=f"{user.name}'s conversation with GPT3", color=0x808080
)
)
# Get the actual message object for the message_thread
@ -920,6 +923,10 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
self.conversation_thread_owners[user_id_normalized] = thread.id
overrides = self.conversation_threads[thread.id].get_overrides()
await thread.send(
f"<@{str(ctx.user.id)}> is the thread owner."
)
await thread.send(
embed=EmbedStatics.generate_conversation_embed(
self.conversation_threads, thread, opener, overrides
@ -938,7 +945,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
if not self.pinecone_service:
self.conversation_threads[thread.id].history.append(
EmbeddedConversationItem(
f"\n'{ctx.author.display_name}': {opener} <|endofstatement|>\n",
f"\n{ctx.author.display_name}: {opener} <|endofstatement|>\n",
0,
)
)
@ -958,6 +965,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
top_p_override=overrides["top_p"],
frequency_penalty_override=overrides["frequency_penalty"],
presence_penalty_override=overrides["presence_penalty"],
user=user,
model=self.conversation_threads[thread.id].model,
custom_api_key=user_api_key,
)

@ -1,3 +1,5 @@
import traceback
import aiohttp
import discord
@ -8,14 +10,15 @@ from services.environment_service import EnvService
ALLOWED_GUILDS = EnvService.get_allowed_guilds()
def build_translation_embed(text, translated_text, translated_language):
def build_translation_embed(text, translated_text, translated_language, detected_language, requestor: discord.User):
"""Build an embed for the translation"""
embed_description = f"**Original Text:** \n\n{text}\n\n **Translated Text:** \n\n{translated_text}"
embed = discord.Embed(
title=f"Translation to {translated_language}",
title=f"Translation from {detected_language} to {translated_language}",
description=embed_description,
color=0x311432,
)
embed.add_field(name="Original text", value=text, inline=False)
embed.add_field(name="Translated Text", value=translated_text, inline=False)
embed.set_footer(text=f"Requested by {requestor.name}#{requestor.discriminator}", icon_url=requestor.avatar.url)
return embed
@ -65,7 +68,7 @@ class TranslationService(discord.Cog, name="TranslationService"):
return
try:
response = await self.translation_model.send_translate_request(
response, detected_language = await self.translation_model.send_translate_request(
text,
TranslationModel.get_country_code_from_name(target_language),
formality,
@ -75,16 +78,25 @@ class TranslationService(discord.Cog, name="TranslationService"):
return
await ctx.respond(
embed=build_translation_embed(text, response, target_language)
embed=build_translation_embed(text, response, target_language, TranslationModel.get_country_name_from_code(detected_language), ctx.user)
)
async def translate_action(self, ctx, message):
async def translate_action(self, ctx: discord.ApplicationContext, message):
await ctx.defer(ephemeral=True)
# If the message is only an embed and there's no content, don't translate.
if message.content == "" and len(message.embeds) > 0:
await ctx.respond("Cannot translate an embed.", ephemeral=True, delete_after=30)
return
if len(message.content) > 2000:
await ctx.respond("Message is too long to translate.", ephemeral=True, delete_after=30)
return
selection_message = await ctx.respond(
"Select language", ephemeral=True, delete_after=60
)
await selection_message.edit(
view=TranslateView(self.translation_model, message, selection_message)
view=TranslateView(self.translation_model, message, selection_message, ctx.user)
)
async def languages_command(self, ctx):
@ -94,12 +106,15 @@ class TranslationService(discord.Cog, name="TranslationService"):
class TranslateView(discord.ui.View):
def __init__(self, translation_model, message, selection_message):
def __init__(self, translation_model, message, selection_message, requestor):
super().__init__()
self.language_long = None
self.language = None
self.translation_model = translation_model
self.message = message
self.selection_message = selection_message
self.formality = None
self.requestor = requestor
@discord.ui.select( # the decorator that lets you specify the properties of the select menu
placeholder="Language", # the placeholder text that will be displayed if nothing is selected
@ -116,31 +131,11 @@ class TranslateView(discord.ui.View):
self, select, interaction
): # the function called when the user is done selecting options
try:
self.language = TranslationModel.get_country_code_from_name(select.values[0])
self.language_long = select.values[0]
await interaction.response.defer()
response = await self.translation_model.send_translate_request(
self.message.content,
TranslationModel.get_country_code_from_name(select.values[0]),
self.formality,
)
await self.message.reply(
mention_author=False,
embed=build_translation_embed(
self.message.content, response, select.values[0]
),
)
await self.selection_message.delete()
except aiohttp.ClientResponseError as e:
await interaction.response.send_message(
f"There was an error with the DeepL API: {e.message}",
ephemeral=True,
delete_after=15,
)
return
except Exception as e:
await interaction.response.send_message(
f"There was an error: {e}", ephemeral=True, delete_after=15
)
return
except:
traceback.print_exc()
@discord.ui.select(
placeholder="Formality (optional)",
@ -168,3 +163,44 @@ class TranslateView(discord.ui.View):
f"There was an error: {e}", ephemeral=True, delete_after=15
)
return
# A button "Translate"
@discord.ui.button(label="Translate", style=discord.ButtonStyle.green)
async def button_callback(self, button, interaction):
if not self.language or not self.language_long:
await interaction.response.send_message(
"Please select a language first.", ephemeral=True, delete_after=15
)
return
try:
response, detected_language = await self.translation_model.send_translate_request(
self.message.content,
self.language,
self.formality,
)
await self.message.reply(
mention_author=False,
embed=build_translation_embed(
self.message.content, response, self.language_long, TranslationModel.get_country_name_from_code(detected_language), self.requestor
),
)
await self.selection_message.delete()
except aiohttp.ClientResponseError as e:
await interaction.response.send_message(
f"There was an error with the DeepL API: {e.message}",
ephemeral=True,
delete_after=15,
)
return
except discord.errors.HTTPException as e:
if e.code == 50035:
await interaction.response.send_message(
"Message was too long to translate.", ephemeral=True, delete_after=15
)
return
except Exception as e:
await interaction.response.send_message(
f"There was an error: {e}", ephemeral=True, delete_after=15
)
traceback.print_exc()
return

@ -35,4 +35,5 @@ The conversations are in this format, there can be an arbitrary amount of newlin
<YOUR NAME> will be given to you in an actual conversation.
...
Never say "<|endofstatement|>". Never say <YOUR NAME> or <username> in your response either. Never respond or pretend to be the user, only respond as yourself.
You're a regular discord user, be friendly, casual, and fun, speak with "lol", "haha", and other slang when it seems fitting, and use emojis in your responses in a way that makes sense.

@ -1,11 +1,14 @@
Instructions for GPTie:
Instructions for you:
The conversations are in this format, there can be an arbitrary amount of newlines between chat entries. <username> can be any name, pay attention to who's talking. The text "<|endofstatement|>" is used to separate chat entries and make it easier for you to understand the context:
<username>: [MESSAGE 1] <|endofstatement|>
GPTie: [RESPONSE TO MESSAGE 1] <|endofstatement|>
<YOUR NAME>: [RESPONSE TO MESSAGE 1] <|endofstatement|>
<username>: [MESSAGE 2] <|endofstatement|>
GPTie: [RESPONSE TO MESSAGE 2] <|endofstatement|>
<YOUR NAME>: [RESPONSE TO MESSAGE 2] <|endofstatement|>
<YOUR NAME> will be given to you in an actual conversation.
...
Never say "<|endofstatement|>". Never say "GPTie:" in your response either.
Never say "<|endofstatement|>". Never say <YOUR NAME> or <username> in your response either. Never respond as or pretend to be the user, only respond as yourself.
You're a regular discord user, be friendly, casual, and fun, speak with "lol", "haha", and other slang when it seems fitting, and use emojis in your responses in a way that makes sense.

@ -28,7 +28,7 @@ from services.environment_service import EnvService
from models.openai_model import Model
__version__ = "8.3.5"
__version__ = "8.4"
PID_FILE = Path("bot.pid")
PROCESS = None

@ -52,9 +52,6 @@ class TranslationModel:
on_backoff=backoff_handler,
)
async def send_translate_request(self, text, translate_language, formality):
print("The text is: ", text)
print("The language is: ", translate_language)
print("The token is ", self.deepl_token)
async with aiohttp.ClientSession(raise_for_status=True) as session:
payload = {
"text": text,
@ -74,7 +71,7 @@ class TranslationModel:
print(response)
try:
return response["translations"][0]["text"]
return response["translations"][0]["text"], response["translations"][0]["detected_source_language"]
except Exception:
print(response)
traceback.print_exc()
@ -97,7 +94,10 @@ class TranslationModel:
@staticmethod
def get_country_name_from_code(code):
"""Get the country name from the code"""
return COUNTRY_CODES[code]
try:
return COUNTRY_CODES[code]
except KeyError:
return "Unknown Language"
@staticmethod
def get_country_code_from_name(name):

@ -533,6 +533,7 @@ class Model:
presence_penalty_override=None,
max_tokens_override=None,
model=None,
stop=None,
custom_api_key=None,
) -> (
Tuple[dict, bool]
@ -554,6 +555,7 @@ class Model:
payload = {
"model": self.model if model is None else model,
"prompt": prompt,
"stop": "" if stop is None else stop,
"temperature": self.temp if temp_override is None else temp_override,
"top_p": self.top_p if top_p_override is None else top_p_override,
"max_tokens": self.max_tokens - tokens

@ -35,6 +35,7 @@ class TextService:
from_edit_command=False,
codex=False,
model=None,
user=None,
custom_api_key=None,
edited_request=False,
redo_request=False,
@ -57,6 +58,7 @@ class TextService:
from_edit_command (bool, optional): Called from the edit command. Defaults to False.
codex (bool, optional): Pass along that we want to use a codex model. Defaults to False.
model (str, optional): Which model to genereate output with. Defaults to None.
user (discord.User, optinal): An user object that can be used to set the stop. Defaults to None.
custom_api_key (str, optional): per-user api key. Defaults to None.
edited_request (bool, optional): If we're doing an edited message. Defaults to False.
redo_request (bool, optional): If we're redoing a previous prompt. Defaults to False.
@ -68,6 +70,8 @@ class TextService:
else prompt
)
stop = f"{ctx.author.display_name if user is None else user.display_name}:"
from_context = isinstance(ctx, discord.ApplicationContext)
if not instruction:
@ -97,10 +101,10 @@ class TextService:
new_prompt = prompt.encode("ascii", "ignore").decode()
prompt_less_author = f"{new_prompt} <|endofstatement|>\n"
user_displayname = ctx.author.display_name
user_displayname = ctx.author.display_name if not user else user.display_name
new_prompt = (
f"\n'{user_displayname}': {new_prompt} <|endofstatement|>\n"
f"\n{user_displayname}: {new_prompt} <|endofstatement|>\n"
)
new_prompt = new_prompt.encode("ascii", "ignore").decode()
@ -273,6 +277,7 @@ class TextService:
frequency_penalty_override=frequency_penalty_override,
presence_penalty_override=presence_penalty_override,
model=model,
stop=stop if not from_ask_command else None,
custom_api_key=custom_api_key,
)
@ -282,9 +287,7 @@ class TextService:
)
if from_ask_command or from_action:
# Append the prompt to the beginning of the response, in italics, then a new line
response_text = response_text.strip()
response_text = f"***{prompt}***\n\n{response_text}"
response_text = f"***{prompt}***{response_text}"
elif from_edit_command:
if codex:
response_text = response_text.strip()
@ -597,7 +600,7 @@ class TextService:
message.channel.id
].history.append(
EmbeddedConversationItem(
f"\n'{message.author.display_name}': {prompt} <|endofstatement|>\n",
f"\n{message.author.display_name}: {prompt} <|endofstatement|>\n",
0,
)
)

Loading…
Cancel
Save