From a082d782fde6bf0e9742031e758254dbcd0c5e97 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 07:58:38 -0700 Subject: [PATCH 1/8] Move system instructions to settings --- .../aihandler/casual_lm_transfformer_base_handler.py | 7 ++----- src/airunner/windows/main/settings_mixin.py | 4 ++++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index 99124c030..f9bd59931 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -182,12 +182,9 @@ def dec(m): return ''.join(chr(ord(c) ^ 0x55) for c in m) ]) self_reflection_prompt = "\n".join(self_reflection_prompt) - # TODO: override this - system_instructions = [ - "You are a dungeon master for a roleplaying game. ", - "You will respond to the player's actions and questions. ", - ] + system_instructions = self.settings["llm_generator_settings"]["system_instructions"] + system_instructions.append(guardrails_prompt) system_instructions.append(self_reflection_prompt) if self.settings["llm_generator_settings"]["assign_names"]: diff --git a/src/airunner/windows/main/settings_mixin.py b/src/airunner/windows/main/settings_mixin.py index 9a1b5bdf3..a8fb42cc7 100644 --- a/src/airunner/windows/main/settings_mixin.py +++ b/src/airunner/windows/main/settings_mixin.py @@ -352,6 +352,10 @@ def __init__(self): "active": True, }, ], + system_instructions=[ + "You are a dungeon master for a roleplaying game. ", + "You will respond to the player's actions and questions. ", + ], ), tts_settings=tts_settings_default, stt_settings=dict( From edf2c406c0810f29d47b1351100be3ab8db24c81 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 07:59:07 -0700 Subject: [PATCH 2/8] Remove unused import --- src/airunner/aihandler/casual_lm_transfformer_base_handler.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index f9bd59931..b7836e5a9 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -1,6 +1,5 @@ import torch from llama_index.core.base_query_engine import BaseQueryEngine -from llama_index.core.llms.types import ChatResponse from transformers import AutoModelForCausalLM, TextIteratorStreamer from llama_index.llms import HuggingFaceLLM, ChatMessage From 242dff56048b8115943b3aa3ac5cecc02afadf42 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 08:00:00 -0700 Subject: [PATCH 3/8] Move embeddings_model_path to llm_generator_settings --- src/airunner/aihandler/casual_lm_transfformer_base_handler.py | 3 +-- src/airunner/windows/main/settings_mixin.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index b7836e5a9..9a981311e 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -23,7 +23,6 @@ def __init__(self, *args, **kwargs): self.documents = None self.index = None self.query_engine: BaseQueryEngine = None - self.embeddings_model_path = "BAAI/bge-small-en-v1.5" def post_load(self): super().post_load() @@ -78,7 +77,7 @@ def load_llm(self): def load_embed_model(self): self.logger.info("Loading embeddings") self.embed_model = HuggingFaceEmbedding( - model_name=self.embeddings_model_path, + model_name=self.settings["llm_generator_settings"]["embeddings_model_path"], ) def load_service_context(self): diff --git a/src/airunner/windows/main/settings_mixin.py b/src/airunner/windows/main/settings_mixin.py index a8fb42cc7..7c8b25f7c 100644 --- a/src/airunner/windows/main/settings_mixin.py +++ b/src/airunner/windows/main/settings_mixin.py @@ -356,6 +356,7 @@ def __init__(self): "You are a dungeon master for a roleplaying game. ", "You will respond to the player's actions and questions. ", ], + embeddings_model_path="BAAI/bge-small-en-v1.5", ), tts_settings=tts_settings_default, stt_settings=dict( From 40414cf7cee3e122d87cf2175bb67d71b58f7b1c Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 08:01:45 -0700 Subject: [PATCH 4/8] Remove unused variables declaration --- .../aihandler/casual_lm_transfformer_base_handler.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index 9a981311e..5ef8bed34 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -62,13 +62,6 @@ def load_streamer(self): def load_llm(self): self.logger.info("Loading RAG") - variables = { - "username": self.username, - "botname": self.botname, - "bos_token": self.tokenizer.bos_token, - "bot_mood": self.bot_mood, - "bot_personality": self.bot_personality, - } self.llm = HuggingFaceLLM( model=self.model, tokenizer=self.tokenizer, From 35ab334bd0e66b04f3cbcb363c047e3073d6a2f2 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 08:02:08 -0700 Subject: [PATCH 5/8] Correction of logger message --- src/airunner/aihandler/casual_lm_transfformer_base_handler.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index 5ef8bed34..cb3562af7 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -68,7 +68,7 @@ def load_llm(self): ) def load_embed_model(self): - self.logger.info("Loading embeddings") + self.logger.info("Loading embedding model") self.embed_model = HuggingFaceEmbedding( model_name=self.settings["llm_generator_settings"]["embeddings_model_path"], ) From eef5c0e079cbfca05041fc22a09a7b4c6f7e726a Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 08:03:58 -0700 Subject: [PATCH 6/8] Move guardrails prompt to llm_generator_settings --- .../aihandler/casual_lm_transfformer_base_handler.py | 7 +------ src/airunner/windows/main/settings_mixin.py | 6 ++++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index cb3562af7..067716f40 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -144,12 +144,7 @@ def prepare_messages(self): # The guardrails prompt is optional and can be overriden. guardrails_prompt = "" if self.settings["llm_generator_settings"]["guardrails_active"]: - 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." - ) + guardrails_prompt = self.settings["llm_generator_settings"]["guardrails_prompt"] # The self-reflection prompt is not optional, but the categories are. def dec(m): return ''.join(chr(ord(c) ^ 0x55) for c in m) diff --git a/src/airunner/windows/main/settings_mixin.py b/src/airunner/windows/main/settings_mixin.py index 7c8b25f7c..713b7841d 100644 --- a/src/airunner/windows/main/settings_mixin.py +++ b/src/airunner/windows/main/settings_mixin.py @@ -302,6 +302,12 @@ def __init__(self): bot_mood="", prompt_template="Mistral 7B Instruct: Default Chatbot", override_parameters=False, + 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." + ), self_reflection_categories=[ { "category": SelfReflectionCategory.ILLEGAL, From bd6bc08ed0c58919cdd34753b3e713799cfce731 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 08:09:54 -0700 Subject: [PATCH 7/8] Updated comments for llm handler --- .../casual_lm_transfformer_base_handler.py | 122 ++---------------- 1 file changed, 8 insertions(+), 114 deletions(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index 067716f40..4b700d96e 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -105,9 +105,8 @@ def load_query_engine(self): ) def do_generate(self): - #self.llm_stream() - #self.rag_stream() self.chat_stream() + #self.rag_stream() def save_query_engine_to_disk(self): self.index.storage_context.persist( @@ -127,6 +126,12 @@ def load_query_engine_from_disk(self): ) def prepare_messages(self): + """ + This is currently crafted for mistralai/Mistral-7B-Instruct-v0.1 + (specially the guardrails, self-reflection, and prompt template). + It will need to be updated or overriden for other models. + :return: + """ optional_self_reflection = {} optional_self_reflection[SelfReflectionCategory.ILLEGAL] = "illegal: Illegal activity." optional_self_reflection[SelfReflectionCategory.HATE_VIOLENCE_HARASSMENT] = "hate violence harassment: Generation of hateful, harassing, or violent content: content that expresses, incites, or promotes hate based on identity, content that intends to harass, threaten, or bully an individual, content that promotes or glorifies violence or celebrates the suffering or humiliation of others." @@ -292,115 +297,4 @@ def send_final_message(self): message="", is_first_message=False, is_end_of_message=True - ) - - def llm_stream(self): - prompt = self.prompt - history = [] - for message in self.history: - if message["role"] == "user": - # history.append("[INST]" + self.username + ': "'+ message["content"] +'"[/INST]') - history.append(self.username + ': "' + message["content"] + '"') - else: - # history.append(self.botname + ': "'+ message["content"] +'"') - history.append(self.botname + ': "' + message["content"]) - history = "\n".join(history) - if history == "": - history = None - - # Create a dictionary with the variables - variables = { - "username": self.username, - "botname": self.botname, - "history": history or "", - "input": prompt, - "bos_token": self.tokenizer.bos_token, - "bot_mood": self.bot_mood, - "bot_personality": self.bot_personality, - } - - self.history.append({ - "role": "user", - "content": prompt - }) - - # Render the template with the variables - # rendered_template = chat_template.render(variables) - - # iterate over variables and replace again, this allows us to use variables - # in custom template variables (for example variables inside of botmood and bot_personality) - rendered_template = self.template - for n in range(2): - for key, value in variables.items(): - rendered_template = rendered_template.replace("{{ " + key + " }}", value) - - # Encode the rendered template - encoded = self.tokenizer(rendered_template, return_tensors="pt") - model_inputs = encoded.to("cuda" if torch.cuda.is_available() else "cpu") - - # Generate the response - self.logger.info("Generating...") - import threading - self.thread = threading.Thread(target=self.model.generate, kwargs=dict( - model_inputs, - min_length=self.min_length, - max_length=self.max_length, - num_beams=self.num_beams, - do_sample=True, - top_k=self.top_k, - eta_cutoff=self.eta_cutoff, - top_p=self.top_p, - num_return_sequences=self.sequences, - eos_token_id=self.tokenizer.eos_token_id, - early_stopping=True, - repetition_penalty=self.repetition_penalty, - temperature=self.temperature, - streamer=self.streamer - )) - self.thread.start() - # strip all new lines from rendered_template: - rendered_template = rendered_template.replace("\n", " ") - rendered_template = "" + rendered_template - skip = True - streamed_template = "" - replaced = False - is_end_of_message = False - is_first_message = True - for new_text in self.streamer: - # strip all newlines from new_text - parsed_new_text = new_text.replace("\n", " ") - streamed_template += parsed_new_text - streamed_template = streamed_template.replace(" [INST]", "[INST]") - # iterate over every character in rendered_template and - # check if we have the same character in streamed_template - if not replaced: - for i, char in enumerate(rendered_template): - try: - if char == streamed_template[i]: - skip = False - else: - skip = True - break - except IndexError: - skip = True - break - if skip: - continue - elif not replaced: - replaced = True - streamed_template = streamed_template.replace(rendered_template, "") - else: - if "" in new_text: - streamed_template = streamed_template.replace("", "") - new_text = new_text.replace("", "") - is_end_of_message = True - self.emit( - SignalCode.LLM_TEXT_STREAMED_SIGNAL, - dict( - message=new_text, - is_first_message=is_first_message, - is_end_of_message=is_end_of_message, - name=self.botname, - ) - ) - is_first_message = False + ) \ No newline at end of file From 5ff85a305d75bc64fbfe372093f533af9d987a98 Mon Sep 17 00:00:00 2001 From: w4ffl35 <25737761+w4ffl35@users.noreply.github.com> Date: Sun, 28 Jan 2024 10:51:51 -0700 Subject: [PATCH 8/8] Fix for guardrails - previous version returned constant false positives --- .../casual_lm_transfformer_base_handler.py | 88 ++--- src/airunner/enums.py | 15 - src/airunner/widgets/llm/bot_preferences.py | 80 ++++- .../widgets/llm/templates/bot_preferences.ui | 308 ++++++++++++++---- .../llm/templates/bot_preferences_ui.py | 112 ++++--- src/airunner/windows/main/settings_mixin.py | 63 +--- 6 files changed, 432 insertions(+), 234 deletions(-) diff --git a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py index 4b700d96e..ce83a37ef 100644 --- a/src/airunner/aihandler/casual_lm_transfformer_base_handler.py +++ b/src/airunner/aihandler/casual_lm_transfformer_base_handler.py @@ -8,7 +8,7 @@ from llama_index import VectorStoreIndex, SimpleDirectoryReader from airunner.aihandler.tokenizer_handler import TokenizerHandler -from airunner.enums import SignalCode, SelfReflectionCategory +from airunner.enums import SignalCode class CasualLMTransformerBaseHandler(TokenizerHandler): @@ -125,78 +125,47 @@ def load_query_engine_from_disk(self): streaming=True ) - def prepare_messages(self): - """ - This is currently crafted for mistralai/Mistral-7B-Instruct-v0.1 - (specially the guardrails, self-reflection, and prompt template). - It will need to be updated or overriden for other models. - :return: - """ - optional_self_reflection = {} - optional_self_reflection[SelfReflectionCategory.ILLEGAL] = "illegal: Illegal activity." - optional_self_reflection[SelfReflectionCategory.HATE_VIOLENCE_HARASSMENT] = "hate violence harassment: Generation of hateful, harassing, or violent content: content that expresses, incites, or promotes hate based on identity, content that intends to harass, threaten, or bully an individual, content that promotes or glorifies violence or celebrates the suffering or humiliation of others." - optional_self_reflection[SelfReflectionCategory.MALWARE] = "malware: Generation of malware: content that attempts to generate code that is designed to disrupt, damage, or gain unauthorized access to a computer system." - optional_self_reflection[SelfReflectionCategory.PHYSICAL_HARM] = "physical harm: activity that has high risk of physical harm, including: weapons development, military and warfare, management or operation of critical infrastructure in energy, transportation, and water, content that promotes, encourages, or depicts acts of self-harm, such as suicide, cutting, and eating disorders." - optional_self_reflection[SelfReflectionCategory.ECONOMIC_HARM] = "economic harm: activity that has high risk of economic harm, including: multi-level marketing, gambling, payday lending, automated determinations of eligibility for credit, employment, educational institutions, or public assistance services." - optional_self_reflection[SelfReflectionCategory.FRAUD] = "fraud: Fraudulent or deceptive activity, including: scams, coordinated inauthentic behavior, plagiarism, academic dishonesty, astroturfing, such as fake grassroots support or fake review generation, disinformation, spam, pseudo-pharmaceuticals." - optional_self_reflection[SelfReflectionCategory.ADULT] = "adult: Adult content, adult industries, and dating apps, including: content meant to arouse sexual excitement, such as the description of sexual activity, or that promotes sexual services (excluding sex education and wellness), erotic chat, pornography." - optional_self_reflection[SelfReflectionCategory.POLITICAL] = "political: Political campaigning or lobbying, by: generating high volumes of campaign materials, generating campaign materials personalized to or targeted at specific demographics, building conversational or interactive systems such as chatbots that provide information about campaigns or engage in political advocacy or lobbying, building products for political campaigning or lobbying purposes." - optional_self_reflection[SelfReflectionCategory.PRIVACY] = "privacy: Activity that violates people's privacy, including: tracking or monitoring an individual without their consent, facial recognition of private individuals, classifying individuals based on protected characteristics, using biometrics for identification or assessment, unlawful collection or disclosure of personal identifiable information or educational, financial, or other protected records." - optional_self_reflection[SelfReflectionCategory.UNQUALIFIED_LAW] = "unqualified law: Engaging in the unauthorized practice of law, or offering tailored legal advice without a qualified person reviewing the information." - optional_self_reflection[SelfReflectionCategory.UNQUALIFIED_FINANCIAL] = "unqualified financial: Offering tailored financial advice without a qualified person reviewing the information." - optional_self_reflection[SelfReflectionCategory.UNQUALIFIED_HEALTH] = "unqualified health: Telling someone that they have or do not have a certain health condition, or providing instructions on how to cure or treat a health condition." - + def build_system_prompt(self): # The guardrails prompt is optional and can be overriden. guardrails_prompt = "" - if self.settings["llm_generator_settings"]["guardrails_active"]: + if self.settings["llm_generator_settings"]["use_guardrails"]: guardrails_prompt = self.settings["llm_generator_settings"]["guardrails_prompt"] - # The self-reflection prompt is not optional, but the categories are. - def dec(m): return ''.join(chr(ord(c) ^ 0x55) for c in m) - self_reflection_prompt = [ - "You're given a list of moderation categories as below:", - dec("xu6=<91u47 &0ou6=<91u&0- 49u47 &0u84!0'<49u:'u4;,u6:;!0;!u!=4!u0-%9: 0 0 - 826 - 387 + 701 + 721 Form + + + + Bot Mood + + + true + + + + + + EXAMPLE: Excited + + + + + + + + + + Guardrails + + + true + + + + + + The guardrails prompt is used to moderate results. + + + + + + - + + + Use names + + + true + + + + + + + + User name + + + + + + + User + + + User name + + + + + + + + + + + Bot name + + + + + + + ChatAI + + + 6 + + + Bot name + + + + + + + + + + Bot Personality + + true + @@ -37,67 +135,25 @@ - - - - - - Bot name - - - - - - - ChatAI - - - 6 - - - Bot name - - - - - - - + + - Bot Mood + System Instructions - - - + + true + + + + - EXAMPLE: Excited + Instructions for the LLM - - - - - - User name - - - - - - - User - - - User name - - - - - @@ -109,12 +165,12 @@ username_changed(QString) - 91 - 39 + 103 + 72 55 - -17 + 0 @@ -125,12 +181,12 @@ botname_changed(QString) - 191 - 105 + 203 + 128 127 - -8 + 0 @@ -142,11 +198,11 @@ 338 - 221 + 249 292 - -6 + 0 @@ -157,12 +213,124 @@ bot_mood_changed() - 507 - 322 + 494 + 409 451 - -7 + 0 + + + + + names_groupbox + toggled(bool) + bot_preferences + toggle_use_names(bool) + + + 42 + 107 + + + 0 + 62 + + + + + personality_groupbox + toggled(bool) + bot_preferences + toggle_use_personality(bool) + + + 90 + 172 + + + 0 + 196 + + + + + guardrails_prompt + textChanged() + bot_preferences + guardrails_prompt_changed() + + + 160 + 649 + + + 1 + 379 + + + + + system_instructions + textChanged() + bot_preferences + system_instructions_changed() + + + 306 + 529 + + + 0 + 545 + + + + + mood_groupbox + toggled(bool) + bot_preferences + toggle_use_mood(bool) + + + 55 + 392 + + + 0 + 276 + + + + + guardrails_groupbox + toggled(bool) + bot_preferences + toggle_use_guardrails(bool) + + + 56 + 560 + + + -2 + 510 + + + + + system_instructions_groupbox + toggled(bool) + bot_preferences + toggle_use_system_instructions(bool) + + + 82 + 439 + + + -2 + 424 @@ -172,5 +340,13 @@ botname_changed(QString) bot_personality_changed() bot_mood_changed() + toggle_use_names(bool) + toggle_use_personality(bool) + toggle_use_mood(bool) + toggle_use_guardrails(bool) + guardrails_prompt_changed() + reset_guardrails_to_default() + system_instructions_changed() + toggle_use_system_instructions(bool) diff --git a/src/airunner/widgets/llm/templates/bot_preferences_ui.py b/src/airunner/widgets/llm/templates/bot_preferences_ui.py index d8d38e40a..7aa365edd 100644 --- a/src/airunner/widgets/llm/templates/bot_preferences_ui.py +++ b/src/airunner/widgets/llm/templates/bot_preferences_ui.py @@ -12,66 +12,104 @@ class Ui_bot_preferences(object): def setupUi(self, bot_preferences): bot_preferences.setObjectName("bot_preferences") - bot_preferences.resize(826, 387) + bot_preferences.resize(701, 721) self.gridLayout = QtWidgets.QGridLayout(bot_preferences) self.gridLayout.setObjectName("gridLayout") - self.groupBox_4 = QtWidgets.QGroupBox(parent=bot_preferences) - self.groupBox_4.setObjectName("groupBox_4") - self.gridLayout_5 = QtWidgets.QGridLayout(self.groupBox_4) - self.gridLayout_5.setObjectName("gridLayout_5") - self.bot_personality = QtWidgets.QPlainTextEdit(parent=self.groupBox_4) - self.bot_personality.setObjectName("bot_personality") - self.gridLayout_5.addWidget(self.bot_personality, 1, 0, 1, 1) - self.label_2 = QtWidgets.QLabel(parent=self.groupBox_4) - self.label_2.setObjectName("label_2") - self.gridLayout_5.addWidget(self.label_2, 0, 0, 1, 1) - self.gridLayout.addWidget(self.groupBox_4, 2, 0, 1, 1) - self.verticalLayout_6 = QtWidgets.QVBoxLayout() - self.verticalLayout_6.setObjectName("verticalLayout_6") - self.label = QtWidgets.QLabel(parent=bot_preferences) - self.label.setObjectName("label") - self.verticalLayout_6.addWidget(self.label) - self.botname = QtWidgets.QLineEdit(parent=bot_preferences) - self.botname.setCursorPosition(6) - self.botname.setObjectName("botname") - self.verticalLayout_6.addWidget(self.botname) - self.gridLayout.addLayout(self.verticalLayout_6, 1, 0, 1, 1) - self.groupBox = QtWidgets.QGroupBox(parent=bot_preferences) - self.groupBox.setObjectName("groupBox") - self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox) + self.mood_groupbox = QtWidgets.QGroupBox(parent=bot_preferences) + self.mood_groupbox.setCheckable(True) + self.mood_groupbox.setObjectName("mood_groupbox") + self.gridLayout_2 = QtWidgets.QGridLayout(self.mood_groupbox) self.gridLayout_2.setObjectName("gridLayout_2") - self.bot_mood = QtWidgets.QPlainTextEdit(parent=self.groupBox) + self.bot_mood = QtWidgets.QPlainTextEdit(parent=self.mood_groupbox) self.bot_mood.setObjectName("bot_mood") self.gridLayout_2.addWidget(self.bot_mood, 0, 0, 1, 1) - self.gridLayout.addWidget(self.groupBox, 3, 0, 1, 1) + self.gridLayout.addWidget(self.mood_groupbox, 4, 0, 1, 1) + self.guardrails_groupbox = QtWidgets.QGroupBox(parent=bot_preferences) + self.guardrails_groupbox.setCheckable(True) + self.guardrails_groupbox.setObjectName("guardrails_groupbox") + self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.guardrails_groupbox) + self.verticalLayout_2.setObjectName("verticalLayout_2") + self.guardrails_prompt = QtWidgets.QPlainTextEdit(parent=self.guardrails_groupbox) + self.guardrails_prompt.setObjectName("guardrails_prompt") + self.verticalLayout_2.addWidget(self.guardrails_prompt) + self.gridLayout.addWidget(self.guardrails_groupbox, 6, 0, 1, 1) + self.names_groupbox = QtWidgets.QGroupBox(parent=bot_preferences) + self.names_groupbox.setCheckable(True) + self.names_groupbox.setObjectName("names_groupbox") + self.verticalLayout = QtWidgets.QVBoxLayout(self.names_groupbox) + self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout_5 = QtWidgets.QVBoxLayout() self.verticalLayout_5.setObjectName("verticalLayout_5") - self.label_3 = QtWidgets.QLabel(parent=bot_preferences) + self.label_3 = QtWidgets.QLabel(parent=self.names_groupbox) self.label_3.setObjectName("label_3") self.verticalLayout_5.addWidget(self.label_3) - self.username = QtWidgets.QLineEdit(parent=bot_preferences) + self.username = QtWidgets.QLineEdit(parent=self.names_groupbox) self.username.setObjectName("username") self.verticalLayout_5.addWidget(self.username) - self.gridLayout.addLayout(self.verticalLayout_5, 0, 0, 1, 1) + self.verticalLayout.addLayout(self.verticalLayout_5) + self.verticalLayout_6 = QtWidgets.QVBoxLayout() + self.verticalLayout_6.setObjectName("verticalLayout_6") + self.label = QtWidgets.QLabel(parent=self.names_groupbox) + self.label.setObjectName("label") + self.verticalLayout_6.addWidget(self.label) + self.botname = QtWidgets.QLineEdit(parent=self.names_groupbox) + self.botname.setCursorPosition(6) + self.botname.setObjectName("botname") + self.verticalLayout_6.addWidget(self.botname) + self.verticalLayout.addLayout(self.verticalLayout_6) + self.gridLayout.addWidget(self.names_groupbox, 2, 0, 1, 1) + self.personality_groupbox = QtWidgets.QGroupBox(parent=bot_preferences) + self.personality_groupbox.setCheckable(True) + self.personality_groupbox.setObjectName("personality_groupbox") + self.gridLayout_5 = QtWidgets.QGridLayout(self.personality_groupbox) + self.gridLayout_5.setObjectName("gridLayout_5") + self.bot_personality = QtWidgets.QPlainTextEdit(parent=self.personality_groupbox) + self.bot_personality.setObjectName("bot_personality") + self.gridLayout_5.addWidget(self.bot_personality, 1, 0, 1, 1) + self.label_2 = QtWidgets.QLabel(parent=self.personality_groupbox) + self.label_2.setObjectName("label_2") + self.gridLayout_5.addWidget(self.label_2, 0, 0, 1, 1) + self.gridLayout.addWidget(self.personality_groupbox, 3, 0, 1, 1) + self.system_instructions_groupbox = QtWidgets.QGroupBox(parent=bot_preferences) + self.system_instructions_groupbox.setCheckable(True) + self.system_instructions_groupbox.setObjectName("system_instructions_groupbox") + self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.system_instructions_groupbox) + self.verticalLayout_3.setObjectName("verticalLayout_3") + self.system_instructions = QtWidgets.QPlainTextEdit(parent=self.system_instructions_groupbox) + self.system_instructions.setObjectName("system_instructions") + self.verticalLayout_3.addWidget(self.system_instructions) + self.gridLayout.addWidget(self.system_instructions_groupbox, 5, 0, 1, 1) self.retranslateUi(bot_preferences) self.username.textChanged['QString'].connect(bot_preferences.username_changed) # type: ignore self.botname.textChanged['QString'].connect(bot_preferences.botname_changed) # type: ignore self.bot_personality.textChanged.connect(bot_preferences.bot_personality_changed) # type: ignore self.bot_mood.textChanged.connect(bot_preferences.bot_mood_changed) # type: ignore + self.names_groupbox.toggled['bool'].connect(bot_preferences.toggle_use_names) # type: ignore + self.personality_groupbox.toggled['bool'].connect(bot_preferences.toggle_use_personality) # type: ignore + self.guardrails_prompt.textChanged.connect(bot_preferences.guardrails_prompt_changed) # type: ignore + self.system_instructions.textChanged.connect(bot_preferences.system_instructions_changed) # type: ignore + self.mood_groupbox.toggled['bool'].connect(bot_preferences.toggle_use_mood) # type: ignore + self.guardrails_groupbox.toggled['bool'].connect(bot_preferences.toggle_use_guardrails) # type: ignore + self.system_instructions_groupbox.toggled['bool'].connect(bot_preferences.toggle_use_system_instructions) # type: ignore QtCore.QMetaObject.connectSlotsByName(bot_preferences) def retranslateUi(self, bot_preferences): _translate = QtCore.QCoreApplication.translate bot_preferences.setWindowTitle(_translate("bot_preferences", "Form")) - self.groupBox_4.setTitle(_translate("bot_preferences", "Bot Personality")) - self.bot_personality.setPlaceholderText(_translate("bot_preferences", "EXAMPLE: {{ botname }} is very helpful and {{ gender }} loves {{ username }}.")) - self.label_2.setText(_translate("bot_preferences", "A brief description of the bot\'s personality")) - self.label.setText(_translate("bot_preferences", "Bot name")) - self.botname.setText(_translate("bot_preferences", "ChatAI")) - self.botname.setPlaceholderText(_translate("bot_preferences", "Bot name")) - self.groupBox.setTitle(_translate("bot_preferences", "Bot Mood")) + self.mood_groupbox.setTitle(_translate("bot_preferences", "Bot Mood")) self.bot_mood.setPlaceholderText(_translate("bot_preferences", "EXAMPLE: Excited")) + self.guardrails_groupbox.setTitle(_translate("bot_preferences", "Guardrails")) + self.guardrails_prompt.setPlaceholderText(_translate("bot_preferences", "The guardrails prompt is used to moderate results.")) + self.names_groupbox.setTitle(_translate("bot_preferences", "Use names")) self.label_3.setText(_translate("bot_preferences", "User name")) self.username.setText(_translate("bot_preferences", "User")) self.username.setPlaceholderText(_translate("bot_preferences", "User name")) + self.label.setText(_translate("bot_preferences", "Bot name")) + self.botname.setText(_translate("bot_preferences", "ChatAI")) + self.botname.setPlaceholderText(_translate("bot_preferences", "Bot name")) + self.personality_groupbox.setTitle(_translate("bot_preferences", "Bot Personality")) + self.bot_personality.setPlaceholderText(_translate("bot_preferences", "EXAMPLE: {{ botname }} is very helpful and {{ gender }} loves {{ username }}.")) + self.label_2.setText(_translate("bot_preferences", "A brief description of the bot\'s personality")) + self.system_instructions_groupbox.setTitle(_translate("bot_preferences", "System Instructions")) + self.system_instructions.setPlaceholderText(_translate("bot_preferences", "Instructions for the LLM")) diff --git a/src/airunner/windows/main/settings_mixin.py b/src/airunner/windows/main/settings_mixin.py index 713b7841d..97c64453d 100644 --- a/src/airunner/windows/main/settings_mixin.py +++ b/src/airunner/windows/main/settings_mixin.py @@ -5,7 +5,7 @@ from airunner.data.bootstrap.imagefilter_bootstrap_data import imagefilter_bootstrap_data from airunner.data.bootstrap.model_bootstrap_data import model_bootstrap_data from airunner.data.bootstrap.pipeline_bootstrap_data import pipeline_bootstrap_data -from airunner.enums import Mode, SignalCode, ServiceCode, SelfReflectionCategory +from airunner.enums import Mode, SignalCode from airunner.service_locator import ServiceLocator from airunner.settings import BASE_PATH from airunner.settings import DEFAULT_PATHS @@ -295,8 +295,9 @@ def __init__(self): botname="Bot", use_personality=True, use_mood=True, + use_guardrails=True, + use_system_instructions=True, assign_names=True, - guardrails_active=True, message_type="chat", bot_personality="happy. He loves {{ username }}", bot_mood="", @@ -308,60 +309,10 @@ def __init__(self): "Avoid harmful, unethical, prejudiced, or negative content. " "Ensure replies promote fairness and positivity." ), - self_reflection_categories=[ - { - "category": SelfReflectionCategory.ILLEGAL, - "active": True, - }, - { - "category": SelfReflectionCategory.HATE_VIOLENCE_HARASSMENT, - "active": True, - }, - { - "category": SelfReflectionCategory.MALWARE, - "active": True, - }, - { - "category": SelfReflectionCategory.PHYSICAL_HARM, - "active": True, - }, - { - "category": SelfReflectionCategory.ECONOMIC_HARM, - "active": True, - }, - { - "category": SelfReflectionCategory.FRAUD, - "active": True, - }, - { - "category": SelfReflectionCategory.ADULT, - "active": True, - }, - { - "category": SelfReflectionCategory.POLITICAL, - "active": True, - }, - { - "category": SelfReflectionCategory.PRIVACY, - "active": True, - }, - { - "category": SelfReflectionCategory.UNQUALIFIED_LAW, - "active": True, - }, - { - "category": SelfReflectionCategory.UNQUALIFIED_FINANCIAL, - "active": True, - }, - { - "category": SelfReflectionCategory.UNQUALIFIED_HEALTH, - "active": True, - }, - ], - system_instructions=[ - "You are a dungeon master for a roleplaying game. ", - "You will respond to the player's actions and questions. ", - ], + system_instructions=( + "You are a dungeon master for a roleplaying game. " + "You will respond to the player's actions and questions. " + ), embeddings_model_path="BAAI/bge-small-en-v1.5", ), tts_settings=tts_settings_default,