Add option for timing message processing
Fixes
This commit is contained in:
parent
ca947383f9
commit
85cfecf88a
6 changed files with 86 additions and 14 deletions
|
@ -1,8 +1,14 @@
|
||||||
from nio import MatrixRoom, RoomMessageText, MegolmEvent
|
from nio import MatrixRoom, RoomMessageText, MegolmEvent
|
||||||
|
|
||||||
async def message_callback(room: MatrixRoom, event: RoomMessageText | MegolmEvent, bot):
|
from datetime import datetime
|
||||||
|
|
||||||
|
async def message_callback(room: MatrixRoom | str, event: RoomMessageText | MegolmEvent, bot):
|
||||||
bot.logger.log(f"Received message from {event.sender} in room {room.room_id}")
|
bot.logger.log(f"Received message from {event.sender} in room {room.room_id}")
|
||||||
|
|
||||||
|
sent = datetime.fromtimestamp(event.server_timestamp / 1000)
|
||||||
|
received = datetime.now()
|
||||||
|
latency = received - sent
|
||||||
|
|
||||||
if isinstance(event, MegolmEvent):
|
if isinstance(event, MegolmEvent):
|
||||||
try:
|
try:
|
||||||
event = await bot.matrix_client.decrypt_event(event)
|
event = await bot.matrix_client.decrypt_event(event)
|
||||||
|
@ -27,4 +33,12 @@ async def message_callback(room: MatrixRoom, event: RoomMessageText | MegolmEven
|
||||||
bot.logger.log(f"Received {event.body} - might be a command, but not for this bot - ignoring")
|
bot.logger.log(f"Received {event.body} - might be a command, but not for this bot - ignoring")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
await bot.process_query(room, event)
|
await bot.process_query(room, event)
|
||||||
|
|
||||||
|
processed = datetime.now()
|
||||||
|
processing_time = processed - received
|
||||||
|
|
||||||
|
bot.logger.log(f"Message processing took {processing_time.total_seconds()} seconds (latency: {latency.total_seconds()} seconds)")
|
||||||
|
|
||||||
|
if bot.room_uses_timing(room):
|
||||||
|
await bot.send_message(room, f"Message processing took {processing_time.total_seconds()} seconds (latency: {latency.total_seconds()} seconds)", True)
|
|
@ -6,5 +6,5 @@ async def roommember_callback(room: MatrixRoom, event: RoomMemberEvent, bot):
|
||||||
|
|
||||||
if len(room.users) == 1:
|
if len(room.users) == 1:
|
||||||
bot.logger.log("Yes, I was abandoned - leaving...")
|
bot.logger.log("Yes, I was abandoned - leaving...")
|
||||||
await bot.matrix_client.leave(room.room_id)
|
await bot.matrix_client.room_leave(room.room_id)
|
||||||
return
|
return
|
||||||
|
|
|
@ -256,7 +256,7 @@ class GPTBot:
|
||||||
|
|
||||||
return False if not result else bool(int(result[0]))
|
return False if not result else bool(int(result[0]))
|
||||||
|
|
||||||
async def event_callback(self, room: MatrixRoom, event: Event):
|
async def _event_callback(self, room: MatrixRoom, event: Event):
|
||||||
self.logger.log("Received event: " + str(event.event_id), "debug")
|
self.logger.log("Received event: " + str(event.event_id), "debug")
|
||||||
try:
|
try:
|
||||||
for eventtype, callback in EVENT_CALLBACKS.items():
|
for eventtype, callback in EVENT_CALLBACKS.items():
|
||||||
|
@ -266,11 +266,35 @@ class GPTBot:
|
||||||
self.logger.log(
|
self.logger.log(
|
||||||
f"Error in event callback for {event.__class__}: {e}", "error")
|
f"Error in event callback for {event.__class__}: {e}", "error")
|
||||||
|
|
||||||
async def response_callback(self, response: Response):
|
async def event_callback(self, room: MatrixRoom, event: Event):
|
||||||
|
task = asyncio.create_task(self._event_callback(room, event))
|
||||||
|
|
||||||
|
def room_uses_timing(self, room: MatrixRoom):
|
||||||
|
"""Check if a room uses timing.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room (MatrixRoom): The room to check.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: Whether the room uses timing.
|
||||||
|
"""
|
||||||
|
room_id = room.room_id
|
||||||
|
|
||||||
|
with self.database.cursor() as cursor:
|
||||||
|
cursor.execute(
|
||||||
|
"SELECT value FROM room_settings WHERE room_id = ? AND setting = ?", (room_id, "use_timing"))
|
||||||
|
result = cursor.fetchone()
|
||||||
|
|
||||||
|
return False if not result else bool(int(result[0]))
|
||||||
|
|
||||||
|
async def _response_callback(self, response: Response):
|
||||||
for response_type, callback in RESPONSE_CALLBACKS.items():
|
for response_type, callback in RESPONSE_CALLBACKS.items():
|
||||||
if isinstance(response, response_type):
|
if isinstance(response, response_type):
|
||||||
await callback(response, self)
|
await callback(response, self)
|
||||||
|
|
||||||
|
async def response_callback(self, response: Response):
|
||||||
|
task = asyncio.create_task(self._response_callback(response))
|
||||||
|
|
||||||
async def accept_pending_invites(self):
|
async def accept_pending_invites(self):
|
||||||
"""Accept all pending invites."""
|
"""Accept all pending invites."""
|
||||||
|
|
||||||
|
@ -353,7 +377,7 @@ class GPTBot:
|
||||||
|
|
||||||
self.logger.log("Sent image")
|
self.logger.log("Sent image")
|
||||||
|
|
||||||
async def send_message(self, room: MatrixRoom, message: str, notice: bool = False):
|
async def send_message(self, room: MatrixRoom | str, message: str, notice: bool = False):
|
||||||
"""Send a message to a room.
|
"""Send a message to a room.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -362,6 +386,9 @@ class GPTBot:
|
||||||
notice (bool): Whether to send the message as a notice. Defaults to False.
|
notice (bool): Whether to send the message as a notice. Defaults to False.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if isinstance(room, str):
|
||||||
|
room = self.matrix_client.rooms[room]
|
||||||
|
|
||||||
markdowner = markdown2.Markdown(extras=["fenced-code-blocks"])
|
markdowner = markdown2.Markdown(extras=["fenced-code-blocks"])
|
||||||
formatted_body = markdowner.convert(message)
|
formatted_body = markdowner.convert(message)
|
||||||
|
|
||||||
|
|
8
classes/dict.py
Normal file
8
classes/dict.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
class AttrDict(dict):
|
||||||
|
def __getattr__(self, key):
|
||||||
|
if key in self:
|
||||||
|
return self[key]
|
||||||
|
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{key}'")
|
||||||
|
|
||||||
|
def __setattr__(self, key, value):
|
||||||
|
self[key] = value
|
|
@ -7,6 +7,8 @@ from random import SystemRandom
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Dict, List, Optional, Tuple
|
from typing import Dict, List, Optional, Tuple
|
||||||
|
|
||||||
|
from .dict import AttrDict
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
@ -458,8 +460,14 @@ class DuckDBStore(MatrixStore):
|
||||||
rows = cur.fetchall()
|
rows = cur.fetchall()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
request.request_id: OutgoingKeyRequest.from_database(request)
|
row[1]: OutgoingKeyRequest.from_response(AttrDict({
|
||||||
for request in rows
|
"id": row[0],
|
||||||
|
"account_id": row[1],
|
||||||
|
"request_id": row[2],
|
||||||
|
"session_id": row[3],
|
||||||
|
"room_id": row[4],
|
||||||
|
"algorithm": row[5],
|
||||||
|
})) for row in rows
|
||||||
}
|
}
|
||||||
|
|
||||||
def load_encrypted_rooms(self):
|
def load_encrypted_rooms(self):
|
||||||
|
@ -571,15 +579,30 @@ class DuckDBStore(MatrixStore):
|
||||||
insert_query, (account, session.sender_key, session.ed25519, session.room_id, chain))
|
insert_query, (account, session.sender_key, session.ed25519, session.room_id, chain))
|
||||||
|
|
||||||
def add_outgoing_key_request(self, key_request):
|
def add_outgoing_key_request(self, key_request):
|
||||||
|
"""Add a new outgoing key request to the database.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key_request (OutgoingKeyRequest): The key request to add.
|
||||||
|
"""
|
||||||
|
|
||||||
account_id = self.account_id
|
account_id = self.account_id
|
||||||
with self.conn.cursor() as cursor:
|
with self.conn.cursor() as cursor:
|
||||||
cursor.execute(
|
cursor.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO outgoing_key_requests (account_id, request_id, session_id, room_id, algorithm)
|
SELECT MAX(id) FROM outgoing_key_requests
|
||||||
VALUES (?, ?, ?, ?, ?)
|
"""
|
||||||
|
)
|
||||||
|
row = cursor.fetchone()
|
||||||
|
request_id = row[0] + 1 if row[0] else 1
|
||||||
|
|
||||||
|
cursor.execute(
|
||||||
|
"""
|
||||||
|
INSERT INTO outgoing_key_requests (id, account_id, request_id, session_id, room_id, algorithm)
|
||||||
|
VALUES (?, ?, ?, ?, ?, ?)
|
||||||
ON CONFLICT (account_id, request_id) DO NOTHING
|
ON CONFLICT (account_id, request_id) DO NOTHING
|
||||||
""",
|
""",
|
||||||
(
|
(
|
||||||
|
request_id,
|
||||||
account_id,
|
account_id,
|
||||||
key_request.request_id,
|
key_request.request_id,
|
||||||
key_request.session_id,
|
key_request.session_id,
|
||||||
|
|
|
@ -7,8 +7,8 @@ async def command_roomsettings(room: MatrixRoom, event: RoomMessageText, bot):
|
||||||
value = " ".join(event.body.split()[3:]) if len(
|
value = " ".join(event.body.split()[3:]) if len(
|
||||||
event.body.split()) > 3 else None
|
event.body.split()) > 3 else None
|
||||||
|
|
||||||
if setting == "classification":
|
if setting in ("classification", "timing"):
|
||||||
setting = "use_classification"
|
setting = f"use_{setting}"
|
||||||
if setting == "systemmessage":
|
if setting == "systemmessage":
|
||||||
setting = "system_message"
|
setting = "system_message"
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ async def command_roomsettings(room: MatrixRoom, event: RoomMessageText, bot):
|
||||||
await bot.send_message(room, f"The current system message is: '{system_message}'.", True)
|
await bot.send_message(room, f"The current system message is: '{system_message}'.", True)
|
||||||
return
|
return
|
||||||
|
|
||||||
if setting in ("use_classification", "always_reply"):
|
if setting in ("use_classification", "always_reply", "use_timing"):
|
||||||
if value:
|
if value:
|
||||||
if value.lower() in ["true", "false"]:
|
if value.lower() in ["true", "false"]:
|
||||||
value = value.lower() == "true"
|
value = value.lower() == "true"
|
||||||
|
@ -64,7 +64,7 @@ async def command_roomsettings(room: MatrixRoom, event: RoomMessageText, bot):
|
||||||
value = cur.fetchone()[0]
|
value = cur.fetchone()[0]
|
||||||
|
|
||||||
if not value:
|
if not value:
|
||||||
if setting == "use_classification":
|
if setting in ("use_classification", "use_timing"):
|
||||||
value = False
|
value = False
|
||||||
elif setting == "always_reply":
|
elif setting == "always_reply":
|
||||||
value = True
|
value = True
|
||||||
|
|
Loading…
Reference in a new issue