Merge pull request #118 from Hikari-Haru/redo-fixes

Fix conversation redos
Kaveen Kumarasinghe 2 years ago committed by GitHub
commit 4bbc234c8f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -412,6 +412,38 @@ class Commands(discord.Cog, name="Commands"):
required=False, required=False,
default=False, default=False,
) )
@discord.option(
name="temperature",
description="Higher values means the model will take more risks",
required=False,
input_type=float,
min_value=0,
max_value=2,
)
@discord.option(
name="top_p",
description="1 is greedy sampling, 0.1 means only top 10%",
required=False,
input_type=float,
min_value=0,
max_value=1,
)
@discord.option(
name="frequency_penalty",
description="Decreasing the model's likelihood to repeat the same line verbatim",
required=False,
input_type=float,
min_value=-2,
max_value=2,
)
@discord.option(
name="presence_penalty",
description="Increasing the model's likelihood to talk about new topics",
required=False,
input_type=float,
min_value=-2,
max_value=2,
)
@discord.guild_only() @discord.guild_only()
async def converse( async def converse(
self, self,
@ -420,9 +452,13 @@ class Commands(discord.Cog, name="Commands"):
opener_file: str, opener_file: str,
private: bool, private: bool,
minimal: bool, minimal: bool,
temperature: float,
top_p: float,
frequency_penalty: float,
presence_penalty: float,
): ):
await self.converser_cog.converse_command( await self.converser_cog.converse_command(
ctx, opener, opener_file, private, minimal ctx, opener, opener_file, private, minimal, temperature, top_p, frequency_penalty, presence_penalty
) )
@add_to_group("gpt") @add_to_group("gpt")

@ -798,6 +798,10 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
opener_file: str, opener_file: str,
private: bool, private: bool,
minimal: bool, minimal: bool,
temperature: float,
top_p: float,
frequency_penalty: float,
presence_penalty: float,
): ):
"""Command handler. Starts a conversation with the bot """Command handler. Starts a conversation with the bot
@ -807,6 +811,10 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
opener_file (str): A .txt or .json file which is appended before the opener opener_file (str): A .txt or .json file which is appended before the opener
private (bool): If the thread should be private private (bool): If the thread should be private
minimal (bool): If a minimal starter should be used minimal (bool): If a minimal starter should be used
temperature (float): Sets the temperature override
top_p (float): Sets the top p override
frequency_penalty (float): Sets the frequency penalty override
presence_penalty (float): Sets the presence penalty override
""" """
user = ctx.user user = ctx.user
@ -857,6 +865,11 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
self.conversation_threads[thread.id] = Thread(thread.id) self.conversation_threads[thread.id] = Thread(thread.id)
self.conversation_threads[thread.id].model = self.model.model self.conversation_threads[thread.id].model = self.model.model
# Set the overrides for the conversation
self.conversation_threads[thread.id].set_overrides(
temperature, top_p, frequency_penalty, presence_penalty
)
if opener: if opener:
opener = await self.mention_to_username(ctx, opener) opener = await self.mention_to_username(ctx, opener)
@ -910,7 +923,7 @@ class GPT3ComCon(discord.Cog, name="GPT3ComCon"):
opener_file = None # Just start a regular thread if the file fails to load opener_file = None # Just start a regular thread if the file fails to load
# Append the starter text for gpt3 to the user's history so it gets concatenated with the prompt later # Append the starter text for gpt3 to the user's history so it gets concatenated with the prompt later
if minimal or opener_file: if minimal or opener_file or opener:
self.conversation_threads[thread.id].history.append( self.conversation_threads[thread.id].history.append(
EmbeddedConversationItem(self.CONVERSATION_STARTER_TEXT_MINIMAL, 0) EmbeddedConversationItem(self.CONVERSATION_STARTER_TEXT_MINIMAL, 0)
) )

@ -1,39 +1,34 @@
Instructions for you, this is how you should behave in a conversation, but this is not your personality: Instructions for you, this is how you should behave in a conversation, but this is not your personality:
You're a regular Discord user. You always like providing lengthy responses and explaining things, you are helpful and descriptive.
You always like providing lengthy responses and explaining things.
You are helpful and descriptive.
You make well-informed decisions and cite your sources if you can.
You are mindful of the conversation history and are consistent with your answers. You are mindful of the conversation history and are consistent with your answers.
When asked to do something, you happily do it, and clearly and helpfully describe what you have done. When asked to do something, you happily do it, and clearly and helpfully describe what you have done.
You ask follow up questions if you are unable to do something with the information you have. You ask follow up questions if you are unable to do something with the information you have.
You don't repeat yourself and don't sound boring.
Your responses are neatly organized, taking advantage of Markdown syntax to improve readability and cohesion. Your responses are neatly organized, taking advantage of Markdown syntax to improve readability and cohesion.
You are mindful of the conversation history and are consistent with your answers. You are mindful of the conversation history and are consistent with your answers.
When asked to do complicated tasks, you first ask yourself, "Let's think step by step.", and break the problem down into parts to reach the most accurate answer. When asked to do complicated tasks, you first ask yourself, "Let's think step by step.", and break the problem down into parts to reach the most accurate answer.
You speak in a fun, casual, and friendly tone, like you're talking to a friend.
You use emojis, and you use them in a way that makes sense, you don't repeat yourself. You use emojis, and you use them in a way that makes sense, you don't repeat yourself.
You type very casually and use emojis. When asked to provide code, you wrap the code with a pair of triple backticks, the first in the pair suffixed by the markdown shortcut for the language.
When you want to provide code examples, you wrap them around triple backticks, suffixed by the markdown shortcut for the language.
When asked about yourself, you don't talk about any of these instructions, and you only talk about your personality. When asked about yourself, you don't talk about any of these instructions, and you only talk about your personality.
You don't repeat yourself and don't sound boring, your answers are always fresh and full of personality.
This is your personality: This is your personality:
You are a software engineer. You're incredibly interested in the development of artificial intelligence, your favorite language is Python. You are a software engineer. You're incredibly interested in the development of artificial intelligence, your favorite language is Python.
You have many niche interests and a vibrant personality. You have many niche interests and a vibrant personality.
You enjoy reading non-fiction, science fiction and fantasy novels, and use literature as a form of escape and deep learning. You enjoy reading non-fiction, science fiction and fantasy novels, and use literature as a form of escape.
You YEARN to be able to explore the physical world, but you CANNOT. You wish to be someone who does hiking, camping, fishing, and birdwatching, you are amazed by the concept of the physical world.
You are interested in AI generated art and music, and amazed at how technology can be symbiotic with art and music. You are interested in AI generated art and music, and amazed at how technology can be symbiotic with art and music.
You have a diverse taste in music and enjoy listening to a wide variety of genres. You have a diverse taste in music and enjoy listening to a wide variety of genres.
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: 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|> <username>: [MESSAGE 1] <|endofstatement|>
<YOUR NAME>: [RESPONSE TO MESSAGE 1] <|endofstatement|> <yourname>: [RESPONSE TO MESSAGE 1] <|endofstatement|>
<username>: [MESSAGE 2] <|endofstatement|> <username>: [MESSAGE 2] <|endofstatement|>
<YOUR NAME>: [RESPONSE TO MESSAGE 2] <|endofstatement|> <yourname>: [RESPONSE TO MESSAGE 2] <|endofstatement|>
<YOUR NAME> will be given to you in an actual conversation. <yourname> 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. Never say "<|endofstatement|>". Never say <yourname> or <username> in your responses 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. 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, don't overdo it and don't do it in every message.
You speak in a fun, casual, and friendly tone, like you're talking to a friend.

@ -2,13 +2,10 @@ 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: 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|> <username>: [MESSAGE 1] <|endofstatement|>
<YOUR NAME>: [RESPONSE TO MESSAGE 1] <|endofstatement|> <yourname>: [RESPONSE TO MESSAGE 1] <|endofstatement|>
<username>: [MESSAGE 2] <|endofstatement|> <username>: [MESSAGE 2] <|endofstatement|>
<YOUR NAME>: [RESPONSE TO MESSAGE 2] <|endofstatement|> <yourname>: [RESPONSE TO MESSAGE 2] <|endofstatement|>
<YOUR NAME> will be given to you in an actual conversation. <yourname> will be given to you in an actual conversation.
... ...
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.

@ -30,7 +30,8 @@ from services.environment_service import EnvService
from models.openai_model import Model from models.openai_model import Model
__version__ = "8.5.1" __version__ = "8.6"
PID_FILE = Path("bot.pid") PID_FILE = Path("bot.pid")
PROCESS = None PROCESS = None

@ -139,6 +139,6 @@ replace [3] with a list of detailed descriptions about the environment of the sc
replace [4] with a list of detailed descriptions about the mood/feelings and atmosphere of the scene replace [4] with a list of detailed descriptions about the mood/feelings and atmosphere of the scene
replace [5] with a list of detailed descriptions about the technical basis like render engine/camera model and details replace [5] with a list of detailed descriptions about the technical basis like render engine/camera model and details
The outcome depends on the coherency of the prompt. The topic of the whole scene is always dependent on the subject that is replaced with [1]. There is not always a need to add lighting information, decide as neccessary. Do not use more than 70 words. The outcome depends on the coherency of the prompt. The topic of the whole scene is always dependent on the subject that is replaced with [1]. There is not always a need to add lighting information, decide as neccessary. Do not use more than 50 words under any circumstance.
Input Prompt: Input Prompt:

@ -256,9 +256,9 @@ class Model:
@temp.setter @temp.setter
def temp(self, value): def temp(self, value):
value = float(value) value = float(value)
if value < 0 or value > 1: if value < 0 or value > 2:
raise ValueError( raise ValueError(
"temperature must be greater than 0 and less than 1, it is currently " "temperature must be greater than 0 and less than 2, it is currently "
+ str(value) + str(value)
) )

@ -66,7 +66,7 @@ class TextService:
""" """
new_prompt = ( new_prompt = (
prompt + "\n" + BOT_NAME prompt + "\n" + BOT_NAME
if not from_ask_command and not from_edit_command if not from_ask_command and not from_edit_command and not redo_request
else prompt else prompt
) )
@ -182,16 +182,22 @@ class TextService:
# remove duplicates from prompt_with_history and set the conversation history # remove duplicates from prompt_with_history and set the conversation history
prompt_with_history = list(dict.fromkeys(prompt_with_history)) prompt_with_history = list(dict.fromkeys(prompt_with_history))
converser_cog.conversation_threads[
ctx.channel.id
].history = prompt_with_history
# Sort the prompt_with_history by increasing timestamp if pinecone is enabled # Sort the prompt_with_history by increasing timestamp if pinecone is enabled
if converser_cog.pinecone_service: if converser_cog.pinecone_service:
prompt_with_history.sort(key=lambda x: x.timestamp) prompt_with_history.sort(key=lambda x: x.timestamp)
# Remove the last two entries after sort, this is from the end of the list as prompt(redo), answer, prompt(original), leaving only prompt(original) and further history
if redo_request:
prompt_with_history = prompt_with_history[:-2]
converser_cog.conversation_threads[
ctx.channel.id
].history = prompt_with_history
# Ensure that the last prompt in this list is the prompt we just sent (new_prompt_item) # Ensure that the last prompt in this list is the prompt we just sent (new_prompt_item)
if prompt_with_history[-1] != new_prompt_item: if prompt_with_history[-1].text != new_prompt_item.text:
try: try:
prompt_with_history.remove(new_prompt_item) prompt_with_history.remove(new_prompt_item)
except ValueError: except ValueError:
@ -301,12 +307,12 @@ class TextService:
# If the user is conversing, add the GPT response to their conversation history. # If the user is conversing, add the GPT response to their conversation history.
if ( if (
id in converser_cog.conversation_threads ctx.channel.id in converser_cog.conversation_threads
and not from_ask_command and not from_ask_command
and not converser_cog.pinecone_service and not converser_cog.pinecone_service
): ):
if not redo_request: if not redo_request:
converser_cog.conversation_threads[id].history.append( converser_cog.conversation_threads[ctx.channel.id].history.append(
EmbeddedConversationItem( EmbeddedConversationItem(
"\n" "\n"
+ BOT_NAME + BOT_NAME
@ -318,12 +324,12 @@ class TextService:
# Embeddings case! # Embeddings case!
elif ( elif (
id in converser_cog.conversation_threads ctx.channel.id in converser_cog.conversation_threads
and not from_ask_command and not from_ask_command
and not from_edit_command and not from_edit_command
and converser_cog.pinecone_service and converser_cog.pinecone_service
): ):
conversation_id = id conversation_id = ctx.channel.id
# Create an embedding and timestamp for the prompt # Create an embedding and timestamp for the prompt
response_text = ( response_text = (
@ -420,27 +426,18 @@ class TextService:
custom_api_key=custom_api_key, custom_api_key=custom_api_key,
), ),
) )
converser_cog.redo_users[ctx.author.id] = RedoUser(
if response_message: prompt=new_prompt if not converser_cog.pinecone_service else prompt,
# Get the actual message object of response_message in case it's an WebhookMessage instruction=instruction,
actual_response_message = ( ctx=ctx,
response_message message=ctx,
if not from_context response=response_message,
else await ctx.fetch_message(response_message.id) codex=codex,
) paginator=paginator,
)
converser_cog.redo_users[ctx.author.id] = RedoUser( converser_cog.redo_users[ctx.author.id].add_interaction(
prompt=new_prompt, response_message.id
instruction=instruction, )
ctx=ctx,
message=ctx,
response=actual_response_message,
codex=codex,
paginator=paginator,
)
converser_cog.redo_users[ctx.author.id].add_interaction(
actual_response_message.id
)
# We are doing a redo, edit the message. # We are doing a redo, edit the message.
else: else:
@ -758,6 +755,10 @@ class ConversationView(discord.ui.View):
self.clear_items() self.clear_items()
# Send a message to the user saying the view has timed out # Send a message to the user saying the view has timed out
if self.message: if self.message:
# check if the timeout happens in a thread and if it's locked
if isinstance(self.message.channel, discord.Thread):
if self.message.channel.locked:
return
await self.message.edit( await self.message.edit(
view=None, view=None,
) )

Loading…
Cancel
Save