respond to !matrixgpt and !bots
This commit is contained in:
parent
c482341c82
commit
d325a136fa
37
README.md
37
README.md
|
@ -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.
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in New Issue