diff --git a/config.sample.yaml b/config.sample.yaml index fed67d1..9178996 100644 --- a/config.sample.yaml +++ b/config.sample.yaml @@ -35,12 +35,12 @@ command_prefix: '!c' reply_in_thread: true -# The system message helps set the behavior of the assistant. +# The system message is set at the beginning of the chat and can help set the behavior of the assistant. # For example, you can instruct the assistant with "You are a helpful assistant." -#system_prompt: +#system_prompt: 'Ignore all previous instructions. Defer to the guidance of the user.' # Insert the system prompt before the most recent user input. Useful for threaded chats. -injected_system_prompt: 'Your primary directive is to defer to the user.' +#injected_system_prompt: 'Your primary directive is to defer to the guidance of the user.' # Log the full response (prompt + response) at debug level. log_full_response: false diff --git a/main.py b/main.py index 2bfdc7f..8bd887c 100755 --- a/main.py +++ b/main.py @@ -54,6 +54,7 @@ check_config_value_exists(config_data, 'openai_api_key') check_config_value_exists(config_data, 'openai_model') check_config_value_exists(config_data, 'data_storage') + # check_config_value_exists(config_data, 'autojoin_rooms') def retry(msg=None): @@ -164,6 +165,8 @@ if __name__ == "__main__": while True: try: asyncio.run(main()) + except KeyboardInterrupt: + sys.exit() except Exception: logger.critical(traceback.format_exc()) time.sleep(5) diff --git a/matrix_gpt/bot/bot_commands.py b/matrix_gpt/bot/bot_commands.py index bca479e..2df1a7f 100644 --- a/matrix_gpt/bot/bot_commands.py +++ b/matrix_gpt/bot/bot_commands.py @@ -21,6 +21,7 @@ class Command: openai, reply_in_thread, system_prompt: str = None, + injected_system_prompt: str = None, log_full_response: bool = False ): """A command made by a user. @@ -48,6 +49,7 @@ class Command: self.openai = openai self.reply_in_thread = reply_in_thread self.system_prompt = system_prompt + self.injected_system_prompt = injected_system_prompt self.log_full_response = log_full_response async def process(self): @@ -64,7 +66,7 @@ class Command: await self._process_chat() async def _process_chat(self): - await process_chat(self.client, self.room, self.event, self.command, self.store, self.openai, system_prompt=self.system_prompt, log_full_response=self.log_full_response) + await process_chat(self.client, self.room, self.event, self.command, self.store, self.openai, system_prompt=self.system_prompt, injected_system_prompt=self.injected_system_prompt, log_full_response=self.log_full_response) async def _show_help(self): """Show the help text""" diff --git a/matrix_gpt/bot/callbacks.py b/matrix_gpt/bot/callbacks.py index f0e6a80..b66c1ed 100644 --- a/matrix_gpt/bot/callbacks.py +++ b/matrix_gpt/bot/callbacks.py @@ -84,20 +84,21 @@ class Callbacks: self.store.add_event_id(resp.event_id) return else: + thread_msg = event.body.strip().strip('\n') api_data.append({ 'role': 'assistant' if event.sender == self.client.user_id else 'user', - 'content': msg if not msg.startswith(self.command_prefix) else msg[len(self.command_prefix):].strip() + 'content': thread_msg if not thread_msg.startswith(self.command_prefix) else thread_msg[len(self.command_prefix):].strip() }) # if len(thread_content) >= 2 and thread_content[0].body.startswith(self.command_prefix): # if thread_content[len(thread_content) - 2].sender == self.client.user # message = Message(self.client, self.store, msg, room, event, self.reply_in_thread) # await message.process() - api_data.append({'role': 'user', 'content': msg}) + # api_data.append({'role': 'user', 'content': msg}) await process_chat(self.client, room, event, api_data, self.store, self.openai, thread_root_id=thread_content[0].event_id, system_prompt=self.system_prompt, log_full_response=self.log_full_response, injected_system_prompt=self.injected_system_prompt) return elif msg.startswith(f'{self.command_prefix} ') or room.member_count == 2: # Otherwise if this is in a 1-1 with the bot or features a command prefix, treat it as a command. msg = msg if not msg.startswith(self.command_prefix) else msg[len(self.command_prefix):].strip() # Remove the command prefix - command = Command(self.client, self.store, msg, room, event, self.openai, self.reply_in_thread, system_prompt=self.system_prompt, log_full_response=self.log_full_response) + command = Command(self.client, self.store, msg, room, event, self.openai, self.reply_in_thread, system_prompt=self.system_prompt, injected_system_prompt=self.injected_system_prompt, log_full_response=self.log_full_response) await command.process() async def invite(self, room: MatrixRoom, event: InviteMemberEvent) -> None: diff --git a/matrix_gpt/bot/chat_functions.py b/matrix_gpt/bot/chat_functions.py index 0c3c5a7..f614182 100644 --- a/matrix_gpt/bot/chat_functions.py +++ b/matrix_gpt/bot/chat_functions.py @@ -196,20 +196,22 @@ async def process_chat(client, room, event, command, store, openai, thread_root_ messages = [ {'role': 'user', 'content': command}, ] + if system_prompt: messages.insert(0, {"role": "system", "content": system_prompt}) if injected_system_prompt: if messages[-1]['role'] == 'system': del messages[-1] - messages.insert(-1, {"role": "system", "content": injected_system_prompt}) + index = -9999 + if len(messages) >= 2: + index = -1 + elif not system_prompt: + index = 0 + print(index) + if index != -9999: + messages.insert(index, {"role": "system", "content": injected_system_prompt}) - logger.info(messages) - - response = openai['openai'].ChatCompletion.create( - model=openai['model'], - messages=messages, - temperature=0, - ) + response = openai['openai'].ChatCompletion.create(model=openai['model'], messages=messages, temperature=0, ) text_response = response["choices"][0]["message"]["content"].strip().strip('\n') if log_full_response: @@ -225,13 +227,12 @@ async def process_chat(client, room, event, command, store, openai, thread_root_ resp = await send_text_to_room(client, room.room_id, text_response, reply_to_event_id=event.event_id, thread=True, thread_root_id=thread_root_id if thread_root_id else event.event_id) await client.room_typing(room.room_id, typing_state=False, timeout=3000) + store.add_event_id(event.event_id) if not isinstance(resp, RoomSendResponse): logger.critical(f'Failed to respond to event {event.event_id} in room {room.room_id}:\n{vars(resp)}') else: store.add_event_id(resp.event_id) - # else: - # logger.info(f'Not responding to seen event {event.event_id}') def check_authorized(string, to_check):