respond to !matrixgpt and !bots

This commit is contained in:
Cyberes 2024-04-07 22:44:27 -06:00
parent c482341c82
commit d325a136fa
5 changed files with 52 additions and 25 deletions

View File

@ -1,39 +1,44 @@
# MatrixGPT
_ChatGPT bot for Matrix._
Uses code from [anoadragon453/nio-template](https://github.com/anoadragon453/nio-template).
_Chatbots for Matrix._
## Install
```bash
sudo apt install libolm-dev gcc python3-dev
pip install -r requirements.txt
```
1. Install requirements:
```bash
sudo apt install libolm-dev gcc python3-dev
pip install -r requirements.txt
```
2. Copy `config.sample.yaml` to `config.yaml` and fill it out with your bot's Matrix auth and your API key(s).
Copy `config.sample.yaml` to `config.yaml` and fill it out with your bot's auth and your OpenAI API key.
[Pantalaimon](https://github.com/matrix-org/pantalaimon) is **required** for the bot to be able to talk in encrypted rooms.
Then invite your bot and start a chat by prefixing your message with `!c`. The bot will create a thread (you don't need
to use `!c` in the thread).
[Pantalaimon](https://github.com/matrix-org/pantalaimon) is **required** for the bot to be able to talk in encrypted
rooms.
I included a sample Systemd service.
## Use
Invite the bot to your room and query it with the command `!c` (this can be changed in the config.)
Invite your bot to a room.
Start a chat by prefixing your message with your trigger (for example, `!c`). The bot will create a thread when it
replies to you and you don't need to use the trigger in the thread.
Don't try to use two bots in the same thread.
You can DM a bot for a private chat. Don't use the trigger prefix in a DM.
The bot will move its read marker when a new message is sent in the room.
The bot can give helpful reactions:
- 🚫 means that the user is not allowed to chat with the bot.
- ❌ means the bot encountered an exception. The bot restarts when it encounters an exception which means it will not be able to respond for a short time after this reaction.
- ❌ means the bot encountered an exception. The bot restarts when it encounters an exception which means it will not be
able to respond for a short time after this reaction.
- ❌ 🔐 means there was a decryption failure.
Use `!matrixgpt` to view the bot's help. The bot also responds to `!bots`.
## Encryption
This bot supports encryption. I recommend using [Pantalaimon](https://github.com/matrix-org/pantalaimon/) to manage encryption keys as the built-in solution is a little janky and may be unreliable.
This bot supports encryption. I recommend using [Pantalaimon](https://github.com/matrix-org/pantalaimon/) to manage
encryption keys as the built-in solution is a little janky and may be unreliable.

View File

@ -7,7 +7,7 @@ from nio import (AsyncClient, InviteMemberEvent, MatrixRoom, MegolmEvent, RoomMe
from .chat_functions import check_authorized, is_thread, check_command_prefix
from .config import global_config
from .handle_actions import do_reply_msg, do_reply_threaded_msg, do_join_channel
from .handle_actions import do_reply_msg, do_reply_threaded_msg, do_join_channel, sound_off
from .matrix import MatrixClientHelper
logger = logging.getLogger('MatrixGPT')
@ -22,7 +22,7 @@ class MatrixBotCallbacks:
async def handle_message(self, room: MatrixRoom, requestor_event: RoomMessageText) -> None:
"""
Callback for when a message event is received
Callback for when a message event is received.
"""
# Mark all messages as read.
mark_read_task = asyncio.create_task(self.client.room_read_markers(room.room_id, requestor_event.event_id, requestor_event.event_id))
@ -35,6 +35,10 @@ class MatrixBotCallbacks:
return
if requestor_event.sender == self.client.user_id:
return
if msg == '!bots' or msg == '!matrixgpt':
logger.debug(f'Message from {requestor_event.sender} in {room.room_id} --> "{msg}"')
await sound_off(room, requestor_event, self.client_helper)
return
command_activated, sent_command_prefix, command_info = check_command_prefix(msg)
if not command_activated and is_thread(requestor_event):

View File

@ -3,7 +3,7 @@ import logging
import traceback
from typing import Union
from nio import RoomSendResponse
from nio import RoomSendResponse, MatrixRoom, RoomMessageText
from matrix_gpt import MatrixClientHelper
from matrix_gpt.api_client_manager import api_client_helper
@ -34,8 +34,8 @@ def assemble_messages(messages: list, mode: str):
async def generate_ai_response(
client_helper: MatrixClientHelper,
room,
event,
room: MatrixRoom,
event: RoomMessageText,
msg: Union[str, list],
command_info: CommandInfo,
thread_root_id: str = None,
@ -104,7 +104,8 @@ async def generate_ai_response(
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
thread_root_id=thread_root_id if thread_root_id else event.event_id,
markdown_convert=True
)
await client.room_typing(room.room_id, typing_state=False, timeout=1000)
if not isinstance(resp, RoomSendResponse):

View File

@ -101,3 +101,22 @@ async def do_join_channel(client_helper: MatrixClientHelper, room: MatrixRoom, e
return
else:
logger.error(f'Unable to join room: {room.room_id}')
async def sound_off(room: MatrixRoom, event: RoomMessageText, client_helper: MatrixClientHelper):
text_response = """## MatrixGPT
<https://git.evulid.cc/cyberes/MatrixGPT>
### Commands
`!matrixgpt` - show this help message\n\n"""
for command in global_config['command']:
text_response = text_response + f"`{command['trigger']}` - Model: {command['model']}. Temperature: {command['temperature']}. Max tokens: {command['max_tokens']}.\n\n"
return await client_helper.send_text_to_room(
room.room_id,
text_response,
reply_to_event_id=event.event_id,
markdown_convert=True
)

View File

@ -119,7 +119,7 @@ class MatrixClientHelper:
return await self.client.room_send(room_id, "m.reaction", content, ignore_unverified_devices=True)
async def send_text_to_room(self, room_id: str, message: str, notice: bool = False,
markdown_convert: bool = True, reply_to_event_id: Optional[str] = None,
markdown_convert: bool = False, reply_to_event_id: Optional[str] = None,
thread: bool = False, thread_root_id: Optional[str] = None, extra_error: Optional[str] = None,
extra_msg: Optional[str] = None) -> Union[RoomSendResponse, ErrorResponse]:
"""Send text to a matrix room.
@ -142,9 +142,7 @@ class MatrixClientHelper:
A RoomSendResponse if the request was successful, else an ErrorResponse.
"""
# Determine whether to ping room members or not
msgtype = "m.notice" if notice else "m.text"
content = {"msgtype": msgtype, "format": "org.matrix.custom.html", "body": message}
if markdown_convert: