diff --git a/matrix_pygmalion_bot/ai/llama_helpers.py b/matrix_pygmalion_bot/ai/llama_helpers.py index 69a1655..72afc1f 100644 --- a/matrix_pygmalion_bot/ai/llama_helpers.py +++ b/matrix_pygmalion_bot/ai/llama_helpers.py @@ -36,11 +36,11 @@ async def get_full_prompt(simple_prompt: str, bot, chat_history): prompt = f"Below is an instruction that describes a task, paired with an input that provides further context. Write a response that appropriately completes the request.\n\n" prompt += f"### Instruction:\nGiven the following character description and scenario, write a script for a dialogue between the human user {bot.user_name} and the fictional AI assistant {bot.name}. Play the role of the character {bot.name}\n\n" prompt += "### Input:\n" - prompt += bot.name + "'s Persona: " + bot.persona + "\n" - prompt += "Scenario: " + bot.scenario + "\n\n" + prompt += bot.name + "'s Persona: " + bot.get_persona() + "\n" + prompt += "Scenario: " + bot.get_scenario() + "\n\n" prompt += "### Response:\n" - for dialogue_item in bot.example_dialogue: + for dialogue_item in bot.get_example_dialogue(): #prompt += "" + "\n" dialogue_item = dialogue_item.replace('{{user}}', user_name) dialogue_item = dialogue_item.replace('{{char}}', ai_name) diff --git a/matrix_pygmalion_bot/ai/pygmalion_helpers.py b/matrix_pygmalion_bot/ai/pygmalion_helpers.py index 338a2d3..78656e2 100644 --- a/matrix_pygmalion_bot/ai/pygmalion_helpers.py +++ b/matrix_pygmalion_bot/ai/pygmalion_helpers.py @@ -18,10 +18,10 @@ logger = logging.getLogger(__name__) async def get_full_prompt(simple_prompt: str, bot, chat_history): # Prompt without history - prompt = bot.name + "'s Persona: " + bot.persona + "\n" - prompt += "Scenario: " + bot.scenario + "\n\n" + prompt = bot.name + "'s Persona: " + bot.get_persona() + "\n" + prompt += "Scenario: " + bot.get_scenario() + "\n\n" - for dialogue_item in bot.example_dialogue: + for dialogue_item in bot.get_example_dialogue(): prompt += "" + "\n" dialogue_item = dialogue_item.replace('{{user}}', 'You') dialogue_item = dialogue_item.replace('{{char}}', bot.name) diff --git a/matrix_pygmalion_bot/ai/stablehorde.py b/matrix_pygmalion_bot/ai/stablehorde.py index 702ffa7..8ac6109 100644 --- a/matrix_pygmalion_bot/ai/stablehorde.py +++ b/matrix_pygmalion_bot/ai/stablehorde.py @@ -99,8 +99,8 @@ async def generate_sync( async def get_full_prompt(simple_prompt: str, bot, chat_history): # Prompt without history - prompt = bot.name + "'s Persona: " + bot.persona + "\n" - prompt += "Scenario: " + bot.scenario + "\n" + prompt = bot.name + "'s Persona: " + bot.get_persona() + "\n" + prompt += "Scenario: " + bot.get_scenario() + "\n" prompt += "" + "\n" #prompt += bot.name + ": " + bot.greeting + "\n" prompt += "You: " + simple_prompt + "\n" @@ -134,8 +134,8 @@ async def get_full_prompt(simple_prompt: str, bot, chat_history): break visible_history = reversed(visible_history) - prompt = bot.name + "'s Persona: " + bot.persona + "\n" - prompt += "Scenario: " + bot.scenario + "\n" + prompt = bot.name + "'s Persona: " + bot.get_persona() + "\n" + prompt += "Scenario: " + bot.get_scenario() + "\n" prompt += "" + "\n" #prompt += bot.name + ": " + bot.greeting + "\n" for chat_item in visible_history: diff --git a/matrix_pygmalion_bot/core.py b/matrix_pygmalion_bot/core.py index 7b0d7b9..2b44c79 100644 --- a/matrix_pygmalion_bot/core.py +++ b/matrix_pygmalion_bot/core.py @@ -60,6 +60,24 @@ class Callbacks(object): english_original_message = None chat_message = self.bot.chat_history.room(room.display_name).add(event.event_id, event.server_timestamp, room.user_name(event.sender), event.sender == self.client.user, is_command, relates_to, event.body, language, english_original_message) + + # parse keywords + self.bot.extra_info = {"persona": [], "scenario": [], "example_dialogue": []} + for i, keyword in enumerate(self.bot.keywords): + if re.search(keyword["regex"], event.body): + self.bot.keywords[i]['active'] = int(keyword["duration"]) + logger.info(f"keyword \"{keyword['regex']}\" detected") + if 'active' in self.bot.keywords[i]: + if self.bot.keywords[i]['active'] > 0: + logger.info(f"keyword \"{keyword['regex']}\" active. (duration {self.bot.keywords[i]['active']})") + if 'example_dialogue' in keyword: + self.bot.extra_info['example_dialogue'].append(keyword['example_dialogue']) + if 'persona' in keyword: + self.bot.extra_info['persona'].append(keyword['persona']) + if 'scenario' in keyword: + self.bot.extra_info['scenario'].append(keyword['scenario']) + self.bot.keywords[i]["active"] -= 1 + if self.bot.not_synced: return logger.info( @@ -73,6 +91,7 @@ class Callbacks(object): # Ignore messages when disabled if "disabled" in self.bot.room_config[room.room_id] and self.bot.room_config[room.room_id]["disabled"] == True and not event.body.startswith('!start'): return + # Ignore messages from ourselves if chat_message.is_own_message: return @@ -300,6 +319,8 @@ class ChatBot(object): self.scenario = None self.greeting = None self.example_dialogue = [] + self.keywords = [] + self.extra_info = {"persona": [], "scenario": [], "example_dialogue": []} self.temperature = 0.90 self.events = [] self.global_tick = 0 @@ -318,6 +339,15 @@ class ChatBot(object): self.greeting = greeting self.example_dialogue = example_dialogue + def get_persona(self): + return ' '.join([self.persona, ' '.join(self.extra_info['persona'])]) + + def get_scenario(self): + return ' '.join([self.scenario, ' '.join(self.extra_info['scenario'])]) + + def get_example_dialogue(self): + return self.example_dialogue + self.extra_info['example_dialogue'] + async def event_loop(self): try: while True: @@ -459,6 +489,10 @@ async def main() -> None: else: example_dialogue = [] bot.character_init(botname, config[section]['persona'].replace("\\n", "\n"), config[section]['scenario'].replace("\\n", "\n"), config[section]['greeting'].replace("\\n", "\n"), example_dialogue) + if config.has_option(section, 'keywords'): + bot.keywords = json.loads(config[section]['keywords']) + else: + bot.keywords = [] if config.has_option(section, 'temperature'): bot.temperature = config[section]['temperature'] if config.has_option(section, 'owner'):