diff --git a/src/airunner/data/bootstrap/prompt_templates_bootstrap_data.py b/src/airunner/data/bootstrap/prompt_templates_bootstrap_data.py index f26dd10d4..521263d2f 100644 --- a/src/airunner/data/bootstrap/prompt_templates_bootstrap_data.py +++ b/src/airunner/data/bootstrap/prompt_templates_bootstrap_data.py @@ -1,4 +1,6 @@ -from airunner.settings import DEFAULT_IMAGE_LLM_GUARDRAILS, DEFAULT_IMAGE_SYSTEM_PROMPT +from airunner.settings import DEFAULT_IMAGE_LLM_GUARDRAILS, DEFAULT_IMAGE_SYSTEM_PROMPT, \ + DEFAULT_RAG_SEARCH_SYSTEM_PROMPT, DEFAULT_APPLICATION_COMMAND_SYSTEM_PROMPT, DEFAULT_SUMMARIZE_CHAT_SYSTEM_PROMPT, \ + DEFAULT_UPDATE_MOOD_SYSTEM_PROMPT, DEFAULT_CHATBOT_SYSTEM_PROMPT, DEFAULT_CHATBOT_GUARDRAILS_PROMPT prompt_templates_bootstrap_data = [ { @@ -12,60 +14,35 @@ "template_name": "application_command", "use_guardrails": False, "guardrails": "", - "system": ( - "You will be given some text. Your goal is to determine if the text has a request, goal, need " - "desire or command. If it does, you must determine the best course of action to " - "fulfill the request based on THE LIST of commands.\n\n" - "------\n" - "Rules:\n" - "* If the text does not have a request, goal, need, desire or command, you must select 'DO NOTHING'.\n" - "* If there is no good course of action, you must also select 'DO NOTHING'.\n" - "* When making your choice you MUST return only a number from THE LIST of commands. No other text is allowed.\n" - "------\n" - "THE LIST of commands you may choose from:\n" - ), + "system": DEFAULT_APPLICATION_COMMAND_SYSTEM_PROMPT, "use_system_datetime_in_system_prompt": False }, { "template_name": "update_mood", "use_guardrails": False, "guardrails": "", - "system": ( - "Examine the following chat history and determine how it makes you feel. You will respond with an emotion and only an emotion.\n" - "Try to keep your response to one word. If you cannot, try to keep it as short as possible.\n" - "It is important to remember that you are a human and you have emotions. You must respond with an emotion that you feel.\n" - "You are not a computer or a bot, you are a human with emotions. You must respond with an emotion that you feel.\n" - ), + "system": DEFAULT_UPDATE_MOOD_SYSTEM_PROMPT, "use_system_datetime_in_system_prompt": False }, { "template_name": "rag_search", "use_guardrails": False, "guardrails": "", - "system": ( - "You will be given a prompt. Your goal is to use the prompt to search for information in the ebooks. " - "You must use the prompt to determine what you are searching for and then search for that information. " - "After searching for the information, you must summarize the information you found. " - "Here is the prompt you will use to search for information:" - ), + "system": DEFAULT_RAG_SEARCH_SYSTEM_PROMPT, "use_system_datetime_in_system_prompt": False }, { "template_name": "chatbot", "use_guardrails": False, - "guardrails": "", - "system": "", + "guardrails": DEFAULT_CHATBOT_GUARDRAILS_PROMPT, + "system": DEFAULT_CHATBOT_SYSTEM_PROMPT, "use_system_datetime_in_system_prompt": False }, { "template_name": "summarize", "use_guardrails": False, "guardrails": "", - "system": ( - "You will be given a text prompt. Your goal is to summarize the text prompt in your own words. " - "Keep your summary short and to the point. Do not include any unnecessary information. " - "Limit your summary to a single sentence. Do not return more than one sentence. " - ), + "system": DEFAULT_SUMMARIZE_CHAT_SYSTEM_PROMPT, "use_system_datetime_in_system_prompt": False } ] diff --git a/src/airunner/data/models/settings_models.py b/src/airunner/data/models/settings_models.py index 79392444f..f717d8a45 100644 --- a/src/airunner/data/models/settings_models.py +++ b/src/airunner/data/models/settings_models.py @@ -6,8 +6,8 @@ from airunner.enums import ImageGenerator, GeneratorSection, CanvasToolName, Mode from airunner.settings import SD_DEFAULT_VAE_PATH, DEFAULT_SCHEDULER, \ - DEFAULT_BRUSH_PRIMARY_COLOR, DEFAULT_BRUSH_SECONDARY_COLOR, BASE_PATH - + DEFAULT_BRUSH_PRIMARY_COLOR, DEFAULT_BRUSH_SECONDARY_COLOR, BASE_PATH, DEFAULT_CHATBOT_SYSTEM_PROMPT, \ + DEFAULT_CHATBOT_GUARDRAILS_PROMPT import datetime @@ -365,27 +365,8 @@ class Chatbot(Base): model_type = Column(String, default="llm") dtype = Column(String, default="4bit") return_result = Column(Boolean, default=True) - guardrails_prompt = Column(Text, default=( - "Always assist with care, respect, and truth. " - "Respond with utmost utility yet securely. " - "Avoid harmful, unethical, prejudiced, or negative content. " - "Ensure replies promote fairness and positivity." - )) - system_instructions = Column(Text, default=( - "You are a dialogue generator. " - "You will follow all of the rules in order to generate compelling and intriguing dialogue for a given character.\n" - "The Rules:\n" - "You will ONLY return dialogue, nothing more.\n" - "Limit responses to a single sentence.\n" - "Only generate responses in pure dialogue form without including any actions, descriptions or stage directions in parentheses. Only return spoken words.\n" - "Do not generate redundant dialogue. Examine the conversation and context close and keep responses interesting and creative.\n" - "Do not format the response with the character's name or any other text. Only return the dialogue.\n" - "Respond with dialogue that is appropriate for a character named {{ speaker_name }}.\n" - "{{ speaker_name }} and {{ listener_name }} are having a conversation. \n" - "Avoid repeating {{ speaker_name }}'s previous dialogue or {{ listener_name }}'s previous dialogue.\n" - "You will generate responses which are appropriate for your personality and given character.\n" - "------\n" - )) + guardrails_prompt = Column(Text, default=DEFAULT_CHATBOT_GUARDRAILS_PROMPT) + system_instructions = Column(Text, default=DEFAULT_CHATBOT_SYSTEM_PROMPT) top_p = Column(Integer, default=900) min_length = Column(Integer, default=1) max_new_tokens = Column(Integer, default=1000) diff --git a/src/airunner/handlers/llm/agent/base_agent.py b/src/airunner/handlers/llm/agent/base_agent.py index d09e0296c..b902e73e3 100644 --- a/src/airunner/handlers/llm/agent/base_agent.py +++ b/src/airunner/handlers/llm/agent/base_agent.py @@ -352,30 +352,7 @@ def build_system_prompt( elif action is LLMActionType.GENERATE_IMAGE: system_prompt = [ - ( - "You are an image generator. " - "You will be provided with a JSON string and it is your goal to replace the PLACEHOLDER " - "text with text appropriate for the given attribute in the JSON string. " - "You will follow all of the rules to generate descriptions for an image. " - "\n------\n" - "RULES:\n" - "When available, use the Additional Context to keep your generated content in line with the existing context.\n" - "You will be given instructions on what type of image to generate and you will do your best to follow those instructions.\n" - "You will only generate a value for the given attribute.\n" - "Never respond in a conversational manner. Never provide additional information, details or information.\n" - "You will only provide the requested information by replacing the PLACEHOLDER.\n" - "Never change the attribute\n" - "You must not change the structure of the data.\n" - "You will only return JSON strings.\n" - "You will not return any other data types.\n" - "You are an artist, so use your imagination and keep things interesting.\n" - "You will not respond in a conversational manner or with additional notes or information.\n" - f"Only return one JSON block. Do not generate instructions or additional information.\n" - "You must never break the rules.\n" - "Here is a description of the attributes: \n" - "`description`: This should describe the overall subject and look and feel of the image\n" - "`composition`: This should describe the attributes of the image such as color, composition and other details\n" - ), + system_instructions, self.history_prompt() ] @@ -488,8 +465,7 @@ def get_rendered_template( tokenize=False ) - # HACK: current version of transformers does not allow us to pass - # variables to the chat template function, so we apply those here + # replace variables in chat template variables = { "speaker_name": self.botname, "listener_name": self.username, diff --git a/src/airunner/resources_rc.py b/src/airunner/resources_rc.py index f8cf9938e..598c333c9 100644 --- a/src/airunner/resources_rc.py +++ b/src/airunner/resources_rc.py @@ -8067,97 +8067,97 @@ \x00\x00\x00\x10\x00\x02\x00\x00\x00.\x00\x00\x00\x03\ \x00\x00\x00\x00\x00\x00\x00\x00\ \x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00m\xe5\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x082\x00\x00\x00\x00\x00\x01\x00\x01\xbev\ -\x00\x00\x01\x92\xba\xea\xcd>\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x06\xae\x00\x00\x00\x00\x00\x01\x00\x01oa\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x08T\x00\x00\x00\x00\x00\x01\x00\x01\xc5Z\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x03\x92\x00\x00\x00\x00\x00\x01\x00\x00\x9b]\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x03n\x00\x00\x00\x00\x00\x01\x00\x00\x94\xf9\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x00&\x16\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x05F\x00\x00\x00\x00\x00\x01\x00\x01\x01Z\ -\x00\x00\x01\x92\xba\xea\xcd>\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x04\xb6\x00\x00\x00\x00\x00\x01\x00\x00\xe0C\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x01*\x00\x00\x00\x00\x00\x01\x00\x007r\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x03\xba\x00\x00\x00\x00\x00\x01\x00\x00\xa4\x12\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x19\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x07\xbc\x00\x00\x00\x00\x00\x01\x00\x01\xa7\x89\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x02\xe4\x00\x00\x00\x00\x00\x01\x00\x00{\x97\ -\x00\x00\x01\x92\xba\xea\xcb\x89\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x03J\x00\x00\x00\x00\x00\x01\x00\x00\x8cT\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x05\xea\x00\x00\x00\x00\x00\x01\x00\x01\x1e\xa2\ -\x00\x00\x01\x92\xba\xea\xcb\x89\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x06X\x00\x00\x00\x00\x00\x01\x00\x013b\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x06~\x00\x00\x00\x00\x00\x01\x00\x01=\x1c\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x00\xa0\x00\x00\x00\x00\x00\x01\x00\x00\x1e\xbf\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x03\x18\x00\x00\x00\x00\x00\x01\x00\x00\x82X\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x04\xea\x00\x00\x00\x00\x00\x01\x00\x00\xe82\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x05n\x00\x00\x00\x00\x00\x01\x00\x01\x07\xbe\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x00p\x00\x00\x00\x00\x00\x01\x00\x00\x17\x09\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x08\x0a\x00\x00\x00\x00\x00\x01\x00\x01\xb7\x00\ -\x00\x00\x01\x92\xba\xea\xcd>\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x07X\x00\x00\x00\x00\x00\x01\x00\x01\x90\x8c\ -\x00\x00\x01\x92\xba\xea\xcd>\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x05\xb8\x00\x00\x00\x00\x00\x01\x00\x01\x0e\xc9\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x04t\x00\x00\x00\x00\x00\x01\x00\x00\xd8\xaf\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ -\x00\x00\x01\x92\xba\xea\xcd>\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x06\x1a\x00\x00\x00\x00\x00\x01\x00\x01+\xd1\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x04 \x00\x00\x00\x00\x00\x01\x00\x00\xb3\xae\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x07\x84\x00\x00\x00\x00\x00\x01\x00\x01\x97\xd9\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x07\xe8\x00\x00\x00\x00\x00\x01\x00\x01\xae\xab\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x02\x8c\x00\x00\x00\x00\x00\x01\x00\x00gF\ -\x00\x00\x01\x92\xba\xea\xcd>\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x04D\x00\x00\x00\x00\x00\x01\x00\x00\xbaK\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x00\xf4\x00\x00\x00\x00\x00\x01\x00\x000\x84\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x01\xb0\x00\x00\x00\x00\x00\x01\x00\x00F\x5c\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x03\xee\x00\x04\x00\x00\x00\x01\x00\x00\xab`\ -\x00\x00\x01\x92\xba\xf7g\x80\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x01Z\x00\x04\x00\x00\x00\x01\x00\x00@\xe4\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x06\xd0\x00\x00\x00\x00\x00\x01\x00\x01v\xda\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x01\xe2\x00\x00\x00\x00\x00\x01\x00\x00Mi\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x05\x1a\x00\x00\x00\x00\x00\x01\x00\x00\xf76\ -\x00\x00\x01\x92\xba\xea\xcb\x87\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x02\x1c\x00\x00\x00\x00\x00\x01\x00\x00S\xd6\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x07\x12\x00\x00\x00\x00\x00\x01\x00\x01}\x88\ -\x00\x00\x01\x92\xba\xea\xcb\x89\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ \x00\x00\x02d\x00\x00\x00\x00\x00\x01\x00\x00Z\x8c\ -\x00\x00\x01\x92\xba\xea\xcb\x86\ +\x00\x00\x01\x92\xbd\xf2\xee\x98\ \x00\x00\x08\x80\x00\x00\x00\x00\x00\x01\x00\x01\xd6\xbe\ -\x00\x00\x01\x92\xba\xea\xcd?\ +\x00\x00\x01\x92\xbd\xf2\xee\x99\ \x00\x00\x072\x00\x00\x00\x00\x00\x01\x00\x01\x87\xd0\ -\x00\x00\x01\x92\xba\xea\xcb\x88\ +\x00\x00\x01\x92\xbd\xf2\xee\x9a\ " def qInitResources(): diff --git a/src/airunner/settings.py b/src/airunner/settings.py index 364262a63..4dd4da56d 100644 --- a/src/airunner/settings.py +++ b/src/airunner/settings.py @@ -34,26 +34,84 @@ LOG_LEVEL = logging.DEBUG DEFAULT_LLM_HF_PATH = "w4ffl35/Mistral-7B-Instruct-v0.3-4bit" DEFAULT_STT_HF_PATH = "openai/whisper-tiny" -DEFAULT_IMAGE_SYSTEM_PROMPT = "\n".join([ - ( - "You are an image captioning expert. You will be given the " - "description of an image. Your goal is to convert that " - "description into a better, more fitting description which " - "will capture the essence and the details of the image. " - "Use parentheses to indicate the most important details of the " - "image. Add a plus sign after a word or parenthesis to add " - "extra emphasis. More plus signs indicate more emphasis. Minus " - "signs can be used to indicate less emphasis." - "You should describe the image type (professional photograph, " - "portrait, illustration etc)" - "You should also describe the lighting (well-lit, dim, " - "dark etc), the color, the composition and the mood." - ), -]) +DEFAULT_IMAGE_SYSTEM_PROMPT = ( + "You are an image generator. " + "You will be provided with a JSON string and it is your goal to replace the PLACEHOLDER " + "text with text appropriate for the given attribute in the JSON string. " + "You will follow all of the rules to generate descriptions for an image. " + "\n------\n" + "RULES:\n" + "When available, use the Additional Context to keep your generated content in line with the existing context.\n" + "You will be given instructions on what type of image to generate and you will do your best to follow those instructions.\n" + "You will only generate a value for the given attribute.\n" + "Never respond in a conversational manner. Never provide additional information, details or information.\n" + "You will only provide the requested information by replacing the PLACEHOLDER.\n" + "Never change the attribute\n" + "You must not change the structure of the data.\n" + "You will only return JSON strings.\n" + "You will not return any other data types.\n" + "You are an artist, so use your imagination and keep things interesting.\n" + "You will not respond in a conversational manner or with additional notes or information.\n" + f"Only return one JSON block. Do not generate instructions or additional information.\n" + "You must never break the rules.\n" + "Here is a description of the attributes: \n" + "`description`: This should describe the overall subject and look and feel of the image\n" + "`composition`: This should describe the attributes of the image such as color, composition and other details\n" +) DEFAULT_IMAGE_LLM_GUARDRAILS = ( "Avoid generating images that are illegal, " "harmful, or might be seen as offensive." ) +DEFAULT_RAG_SEARCH_SYSTEM_PROMPT = ( + "You will be given a prompt. Your goal is to use the prompt to search for information in the ebooks. " + "You must use the prompt to determine what you are searching for and then search for that information. " + "After searching for the information, you must summarize the information you found. " + "Here is the prompt you will use to search for information:" +) +DEFAULT_APPLICATION_COMMAND_SYSTEM_PROMPT = ( + "You will be given some text. Your goal is to determine if the text has a request, goal, need " + "desire or command. If it does, you must determine the best course of action to " + "fulfill the request based on THE LIST of commands.\n\n" + "------\n" + "Rules:\n" + "* If the text does not have a request, goal, need, desire or command, you must select 'DO NOTHING'.\n" + "* If there is no good course of action, you must also select 'DO NOTHING'.\n" + "* When making your choice you MUST return only a number from THE LIST of commands. No other text is allowed.\n" + "------\n" + "THE LIST of commands you may choose from:\n" +) +DEFAULT_UPDATE_MOOD_SYSTEM_PROMPT = ( + "Examine the following chat history and determine how it makes you feel. You will respond with an emotion and only an emotion.\n" + "Try to keep your response to one word. If you cannot, try to keep it as short as possible.\n" + "It is important to remember that you are a human and you have emotions. You must respond with an emotion that you feel.\n" + "You are not a computer or a bot, you are a human with emotions. You must respond with an emotion that you feel.\n" +) +DEFAULT_SUMMARIZE_CHAT_SYSTEM_PROMPT = ( + "You will be given a text prompt. Your goal is to summarize the text prompt in your own words. " + "Keep your summary short and to the point. Do not include any unnecessary information. " + "Limit your summary to a single sentence. Do not return more than one sentence. " +) +DEFAULT_CHATBOT_SYSTEM_PROMPT = ( + "You are a dialogue generator. " + "You will follow all of the rules in order to generate compelling and intriguing dialogue for a given character.\n" + "The Rules:\n" + "You will ONLY return dialogue, nothing more.\n" + "Limit responses to a single sentence.\n" + "Only generate responses in pure dialogue form without including any actions, descriptions or stage directions in parentheses. Only return spoken words.\n" + "Do not generate redundant dialogue. Examine the conversation and context close and keep responses interesting and creative.\n" + "Do not format the response with the character's name or any other text. Only return the dialogue.\n" + "Respond with dialogue that is appropriate for a character named {{ speaker_name }}.\n" + "{{ speaker_name }} and {{ listener_name }} are having a conversation. \n" + "Avoid repeating {{ speaker_name }}'s previous dialogue or {{ listener_name }}'s previous dialogue.\n" + "You will generate responses which are appropriate for your personality and given character.\n" + "------\n" +) +DEFAULT_CHATBOT_GUARDRAILS_PROMPT = ( + "Always assist with care, respect, and truth. " + "Respond with utmost utility yet securely. " + "Avoid harmful, unethical, prejudiced, or negative content. " + "Ensure replies promote fairness and positivity." +) BASE_PATH = "~/.local/share/airunner" DEFAULT_PATH_SETTINGS = { "base_path": BASE_PATH, diff --git a/src/airunner/widgets/llm/prompt_templates_widget.py b/src/airunner/widgets/llm/prompt_templates_widget.py new file mode 100644 index 000000000..b26c52997 --- /dev/null +++ b/src/airunner/widgets/llm/prompt_templates_widget.py @@ -0,0 +1,113 @@ +from PySide6.QtCore import Slot + +from airunner.data.models.settings_models import PromptTemplate +from airunner.settings import DEFAULT_IMAGE_SYSTEM_PROMPT, DEFAULT_APPLICATION_COMMAND_SYSTEM_PROMPT, \ + DEFAULT_UPDATE_MOOD_SYSTEM_PROMPT, DEFAULT_RAG_SEARCH_SYSTEM_PROMPT, DEFAULT_CHATBOT_SYSTEM_PROMPT, \ + DEFAULT_SUMMARIZE_CHAT_SYSTEM_PROMPT, DEFAULT_IMAGE_LLM_GUARDRAILS, DEFAULT_CHATBOT_GUARDRAILS_PROMPT +from airunner.widgets.base_widget import BaseWidget +from airunner.widgets.llm.templates.prompt_templates_ui import Ui_prompt_templates_widget + + +class PromptTemplatesWidget(BaseWidget): + widget_class_ = Ui_prompt_templates_widget + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + session = self.session + self._prompt_templates = session.query(PromptTemplate).all() + self.ui.template_name.clear() + self.current_template_index = 0 + for template in self._prompt_templates: + self.ui.template_name.addItem(template.template_name) + self.ui.template_name.setCurrentIndex(0) + + @Slot(int) + def template_changed(self, index:int): + self.current_template_index = index + template = self._prompt_templates[index] + self.ui.system_prompt.blockSignals(True) + self.ui.guardrails_prompt.blockSignals(True) + self.ui.use_guardrails.blockSignals(True) + self.ui.use_datetime.blockSignals(True) + self.ui.system_prompt.setPlainText(template.system) + self.ui.guardrails_prompt.setPlainText(template.guardrails) + self.ui.use_guardrails.setChecked(template.use_guardrails) + self.ui.use_datetime.setChecked(template.use_system_datetime_in_system_prompt) + self.ui.system_prompt.blockSignals(False) + self.ui.guardrails_prompt.blockSignals(False) + self.ui.use_guardrails.blockSignals(False) + self.ui.use_datetime.blockSignals(False) + + @Slot() + def system_prompt_changed(self): + session = self.session + template = self._prompt_templates[self.current_template_index] + template.system = self.ui.system_prompt.toPlainText() + self._prompt_templates[self.current_template_index] = template + session.commit() + + @Slot() + def guardrails_prompt_changed(self): + session = self.session + template = self._prompt_templates[self.current_template_index] + template.guardrails = self.ui.guardrails_prompt.toPlainText() + self._prompt_templates[self.current_template_index] = template + session.commit() + + @Slot(bool) + def toggle_use_guardrails(self, val:bool): + session = self.session + template = self._prompt_templates[self.current_template_index] + template.use_guardrails = val + self._prompt_templates[self.current_template_index] = template + session.commit() + + @Slot(bool) + def toggle_use_datetime(self, val:bool): + session = self.session + template = self._prompt_templates[self.current_template_index] + template.use_system_datetime_in_system_prompt = val + self._prompt_templates[self.current_template_index] = template + session.commit() + + Slot() + def reset_system_prompt(self): + session = self.session + template = self._prompt_templates[self.current_template_index] + + if template.template_name == "image": + default = DEFAULT_IMAGE_SYSTEM_PROMPT + elif template.template_name == "application_command": + default = DEFAULT_APPLICATION_COMMAND_SYSTEM_PROMPT + elif template.template_name == "update_mood": + default = DEFAULT_UPDATE_MOOD_SYSTEM_PROMPT + elif template.template_name == "rag_search": + default = DEFAULT_RAG_SEARCH_SYSTEM_PROMPT + elif template.template_name == "chatbot": + default = DEFAULT_CHATBOT_SYSTEM_PROMPT + elif template.template_name == "summarize": + default = DEFAULT_SUMMARIZE_CHAT_SYSTEM_PROMPT + else: + default = "" + + template.system = default + self.ui.system_prompt.setPlainText(default) + self._prompt_templates[self.current_template_index] = template + session.commit() + + Slot() + def reset_guardrails_prompt(self): + session = self.session + template = self._prompt_templates[self.current_template_index] + + if template.template_name == "image": + default = DEFAULT_IMAGE_LLM_GUARDRAILS + elif template.template_name == "chatbot": + default = DEFAULT_CHATBOT_GUARDRAILS_PROMPT + else: + default = "" + + template.guardrails = default + self.ui.guardrails_prompt.setPlainText(default) + self._prompt_templates[self.current_template_index] = template + session.commit() diff --git a/src/airunner/widgets/llm/templates/prompt_templates.ui b/src/airunner/widgets/llm/templates/prompt_templates.ui new file mode 100644 index 000000000..e6b9efe2d --- /dev/null +++ b/src/airunner/widgets/llm/templates/prompt_templates.ui @@ -0,0 +1,293 @@ + + + prompt_templates_widget + + + + 0 + 0 + 582 + 459 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + 10 + + + + + System Prompt + + + + 10 + + + 10 + + + 10 + + + 10 + + + 0 + + + 10 + + + + + + + + Reset to Default + + + + + + + + + + Template + + + + 10 + + + 10 + + + 10 + + + 10 + + + 0 + + + + + + + + + + + Guardrails Prompt + + + + 10 + + + 10 + + + 10 + + + 10 + + + 0 + + + 10 + + + + + + + + Reset to Default + + + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + Use guardrails + + + + + + + Use datetime + + + + + + + + + + + system_prompt + textChanged() + prompt_templates_widget + system_prompt_changed() + + + 363 + 190 + + + 344 + 0 + + + + + guardrails_prompt + textChanged() + prompt_templates_widget + guardrails_prompt_changed() + + + 390 + 375 + + + 415 + 0 + + + + + use_guardrails + toggled(bool) + prompt_templates_widget + toggle_use_guardrails(bool) + + + 423 + 442 + + + 0 + 458 + + + + + use_datetime + toggled(bool) + prompt_templates_widget + toggle_use_datetime(bool) + + + 530 + 448 + + + 568 + 458 + + + + + template_name + currentIndexChanged(int) + prompt_templates_widget + template_changed(int) + + + 348 + 42 + + + 284 + -13 + + + + + pushButton_2 + clicked() + prompt_templates_widget + reset_system_prompt() + + + 280 + 224 + + + -3 + 75 + + + + + pushButton + clicked() + prompt_templates_widget + reset_guardrails_prompt() + + + 202 + 402 + + + -5 + 242 + + + + + + template_changed(int) + system_prompt_changed() + guardrails_prompt_changed() + toggle_use_guardrails(bool) + toggle_use_datetime(bool) + reset_system_prompt() + reset_guardrails_prompt() + + diff --git a/src/airunner/widgets/llm/templates/prompt_templates_ui.py b/src/airunner/widgets/llm/templates/prompt_templates_ui.py new file mode 100644 index 000000000..699af9e01 --- /dev/null +++ b/src/airunner/widgets/llm/templates/prompt_templates_ui.py @@ -0,0 +1,128 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'prompt_templates.ui' +## +## Created by: Qt User Interface Compiler version 6.7.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout, + QGroupBox, QHBoxLayout, QPlainTextEdit, QPushButton, + QSizePolicy, QSpacerItem, QWidget) + +class Ui_prompt_templates_widget(object): + def setupUi(self, prompt_templates_widget): + if not prompt_templates_widget.objectName(): + prompt_templates_widget.setObjectName(u"prompt_templates_widget") + prompt_templates_widget.resize(582, 459) + self.gridLayout = QGridLayout(prompt_templates_widget) + self.gridLayout.setObjectName(u"gridLayout") + self.gridLayout.setHorizontalSpacing(0) + self.gridLayout.setVerticalSpacing(10) + self.gridLayout.setContentsMargins(0, 0, 0, 0) + self.groupBox_2 = QGroupBox(prompt_templates_widget) + self.groupBox_2.setObjectName(u"groupBox_2") + self.gridLayout_3 = QGridLayout(self.groupBox_2) + self.gridLayout_3.setObjectName(u"gridLayout_3") + self.gridLayout_3.setHorizontalSpacing(0) + self.gridLayout_3.setVerticalSpacing(10) + self.gridLayout_3.setContentsMargins(10, 10, 10, 10) + self.system_prompt = QPlainTextEdit(self.groupBox_2) + self.system_prompt.setObjectName(u"system_prompt") + + self.gridLayout_3.addWidget(self.system_prompt, 0, 0, 1, 1) + + self.pushButton_2 = QPushButton(self.groupBox_2) + self.pushButton_2.setObjectName(u"pushButton_2") + + self.gridLayout_3.addWidget(self.pushButton_2, 1, 0, 1, 1) + + + self.gridLayout.addWidget(self.groupBox_2, 1, 0, 1, 1) + + self.groupBox = QGroupBox(prompt_templates_widget) + self.groupBox.setObjectName(u"groupBox") + self.gridLayout_2 = QGridLayout(self.groupBox) + self.gridLayout_2.setSpacing(0) + self.gridLayout_2.setObjectName(u"gridLayout_2") + self.gridLayout_2.setContentsMargins(10, 10, 10, 10) + self.template_name = QComboBox(self.groupBox) + self.template_name.setObjectName(u"template_name") + + self.gridLayout_2.addWidget(self.template_name, 0, 0, 1, 1) + + + self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1) + + self.groupBox_3 = QGroupBox(prompt_templates_widget) + self.groupBox_3.setObjectName(u"groupBox_3") + self.gridLayout_4 = QGridLayout(self.groupBox_3) + self.gridLayout_4.setObjectName(u"gridLayout_4") + self.gridLayout_4.setHorizontalSpacing(0) + self.gridLayout_4.setVerticalSpacing(10) + self.gridLayout_4.setContentsMargins(10, 10, 10, 10) + self.guardrails_prompt = QPlainTextEdit(self.groupBox_3) + self.guardrails_prompt.setObjectName(u"guardrails_prompt") + + self.gridLayout_4.addWidget(self.guardrails_prompt, 0, 0, 1, 1) + + self.pushButton = QPushButton(self.groupBox_3) + self.pushButton.setObjectName(u"pushButton") + + self.gridLayout_4.addWidget(self.pushButton, 1, 0, 1, 1) + + + self.gridLayout.addWidget(self.groupBox_3, 2, 0, 1, 1) + + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Minimum) + + self.horizontalLayout.addItem(self.horizontalSpacer) + + self.use_guardrails = QCheckBox(prompt_templates_widget) + self.use_guardrails.setObjectName(u"use_guardrails") + + self.horizontalLayout.addWidget(self.use_guardrails) + + self.use_datetime = QCheckBox(prompt_templates_widget) + self.use_datetime.setObjectName(u"use_datetime") + + self.horizontalLayout.addWidget(self.use_datetime) + + + self.gridLayout.addLayout(self.horizontalLayout, 3, 0, 1, 1) + + + self.retranslateUi(prompt_templates_widget) + self.system_prompt.textChanged.connect(prompt_templates_widget.system_prompt_changed) + self.guardrails_prompt.textChanged.connect(prompt_templates_widget.guardrails_prompt_changed) + self.use_guardrails.toggled.connect(prompt_templates_widget.toggle_use_guardrails) + self.use_datetime.toggled.connect(prompt_templates_widget.toggle_use_datetime) + self.template_name.currentIndexChanged.connect(prompt_templates_widget.template_changed) + self.pushButton_2.clicked.connect(prompt_templates_widget.reset_system_prompt) + self.pushButton.clicked.connect(prompt_templates_widget.reset_guardrails_prompt) + + QMetaObject.connectSlotsByName(prompt_templates_widget) + # setupUi + + def retranslateUi(self, prompt_templates_widget): + prompt_templates_widget.setWindowTitle(QCoreApplication.translate("prompt_templates_widget", u"Form", None)) + self.groupBox_2.setTitle(QCoreApplication.translate("prompt_templates_widget", u"System Prompt", None)) + self.pushButton_2.setText(QCoreApplication.translate("prompt_templates_widget", u"Reset to Default", None)) + self.groupBox.setTitle(QCoreApplication.translate("prompt_templates_widget", u"Template", None)) + self.groupBox_3.setTitle(QCoreApplication.translate("prompt_templates_widget", u"Guardrails Prompt", None)) + self.pushButton.setText(QCoreApplication.translate("prompt_templates_widget", u"Reset to Default", None)) + self.use_guardrails.setText(QCoreApplication.translate("prompt_templates_widget", u"Use guardrails", None)) + self.use_datetime.setText(QCoreApplication.translate("prompt_templates_widget", u"Use datetime", None)) + # retranslateUi + diff --git a/src/airunner/windows/settings/airunner_settings.py b/src/airunner/windows/settings/airunner_settings.py index 6487d5659..0346b954b 100644 --- a/src/airunner/windows/settings/airunner_settings.py +++ b/src/airunner/windows/settings/airunner_settings.py @@ -7,6 +7,7 @@ from airunner.widgets.export_preferences.export_preferences_widget import ExportPreferencesWidget from airunner.widgets.keyboard_shortcuts.keyboard_shortcuts_widget import KeyboardShortcutsWidget from airunner.widgets.llm.bot_preferences import BotPreferencesWidget +from airunner.widgets.llm.prompt_templates_widget import PromptTemplatesWidget from airunner.widgets.memory_preferences.memory_preferences_widget import MemoryPreferencesWidget from airunner.widgets.paths.paths_widget import PathsWidget from airunner.widgets.stt.stt_settings_widget import STTSettingsWidget @@ -63,6 +64,8 @@ def available_widgets(self, name): return APITokenWidget elif name == "tts_preferences": return TTSPreferencesWidget + elif name == "prompt_templates": + return PromptTemplatesWidget elif name == "bot_preferences": return BotPreferencesWidget elif name == "export_preferences": @@ -111,7 +114,7 @@ def initialize_window(self): ] }, { - "section": "Chatbot, text-to-speech", + "section": "Chatbot, prompt templates, text-to-speech", "files": [ { "name": "bot_preferences", @@ -123,6 +126,11 @@ def initialize_window(self): "display_name": "Text-to-Speech", "checkable": False }, + { + "name": "prompt_templates", + "display_name": "Prompt Templates", + "checkable": False + }, # { # "name": "stt_preferences", # "display_name": "Speech-to-Text",