Support markdown message for better display code

This commit is contained in:
hibobmaster 2023-04-11 13:41:26 +08:00
parent a2a83930e9
commit f5ccc67258
Signed by: bobmaster
GPG key ID: 316B77D7914D713C
8 changed files with 62 additions and 19 deletions

View file

@ -9,3 +9,4 @@ BING_API_ENDPOINT="xxxxxxxxxxxxxxx" # Optional, for !bing command
ACCESS_TOKEN="xxxxxxxxxxxxxxxxxxxxx" # Optional, use user_id and password is recommended ACCESS_TOKEN="xxxxxxxxxxxxxxxxxxxxx" # Optional, use user_id and password is recommended
JAILBREAKENABLED="true" # Optional JAILBREAKENABLED="true" # Optional
BING_AUTH_COOKIE="xxxxxxxxxxxxxxxxxxx" # _U cookie, Optional, for Bing Image Creator BING_AUTH_COOKIE="xxxxxxxxxxxxxxxxxxx" # _U cookie, Optional, for Bing Image Creator
MARKDOWN_FORMATTED="true" # Optional

1
.gitignore vendored
View file

@ -28,6 +28,7 @@ share/python-wheels/
MANIFEST MANIFEST
db db
bot.log bot.log
Dockerfile_dev
# image generation folder # image generation folder
images/ images/

View file

@ -71,7 +71,7 @@ python main.py
To interact with the bot, simply send a message to the bot in the Matrix room with one of the two prompts:<br> To interact with the bot, simply send a message to the bot in the Matrix room with one of the two prompts:<br>
- `!gpt` To generate a response using free_endpoint API: - `!gpt` To generate a one time response:
``` ```
!gpt What is the meaning of life? !gpt What is the meaning of life?

View file

@ -4,6 +4,7 @@ import json
from log import getlogger from log import getlogger
logger = getlogger() logger = getlogger()
class askGPT: class askGPT:
def __init__(self): def __init__(self):
self.session = aiohttp.ClientSession() self.session = aiohttp.ClientSession()

33
bot.py
View file

@ -44,11 +44,12 @@ class Bot:
"CHATGPT_API_ENDPOINT") or "https://api.openai.com/v1/chat/completions", "CHATGPT_API_ENDPOINT") or "https://api.openai.com/v1/chat/completions",
api_key: Optional[str] = os.environ.get("OPENAI_API_KEY") or "", api_key: Optional[str] = os.environ.get("OPENAI_API_KEY") or "",
room_id: Union[str, None] = None, room_id: Union[str, None] = None,
bing_api_endpoint: Optional[str] = '', bing_api_endpoint: Union[str, None] = None,
password: Union[str, None] = None, password: Union[str, None] = None,
access_token: Union[str, None] = None, access_token: Union[str, None] = None,
jailbreakEnabled: Optional[bool] = True, jailbreakEnabled: Union[bool, None] = True,
bing_auth_cookie: Optional[str] = '', bing_auth_cookie: Union[str, None] = '',
markdown_formatted: Union[bool, None] = False,
): ):
if (homeserver is None or user_id is None if (homeserver is None or user_id is None
or device_id is None): or device_id is None):
@ -56,7 +57,7 @@ class Bot:
sys.exit(1) sys.exit(1)
if (password is None and access_token is None): if (password is None and access_token is None):
logger.warning("password and access_toekn is required") logger.warning("password or access_toekn is required")
sys.exit(1) sys.exit(1)
self.homeserver = homeserver self.homeserver = homeserver
@ -67,9 +68,27 @@ class Bot:
self.room_id = room_id self.room_id = room_id
self.api_key = api_key self.api_key = api_key
self.chatgpt_api_endpoint = chatgpt_api_endpoint self.chatgpt_api_endpoint = chatgpt_api_endpoint
if bing_api_endpoint is None:
self.bing_api_endpoint = ''
else:
self.bing_api_endpoint = bing_api_endpoint self.bing_api_endpoint = bing_api_endpoint
if jailbreakEnabled is None:
self.jailbreakEnabled = True
else:
self.jailbreakEnabled = jailbreakEnabled self.jailbreakEnabled = jailbreakEnabled
if bing_auth_cookie is None:
self.bing_auth_cookie = ''
else:
self.bing_auth_cookie = bing_auth_cookie self.bing_auth_cookie = bing_auth_cookie
if markdown_formatted is None:
self.markdown_formatted = False
else:
self.markdown_formatted = markdown_formatted
# initialize AsyncClient object # initialize AsyncClient object
self.store_path = os.getcwd() self.store_path = os.getcwd()
self.config = AsyncClientConfig(store=SqliteStore, self.config = AsyncClientConfig(store=SqliteStore,
@ -485,7 +504,7 @@ class Bot:
text = text.strip() text = text.strip()
try: try:
await send_room_message(self.client, room_id, reply_message=text, await send_room_message(self.client, room_id, reply_message=text,
reply_to_event_id="", sender_id=sender_id, user_message=raw_user_message) reply_to_event_id="", sender_id=sender_id, user_message=raw_user_message, markdown_formatted=self.markdown_formatted)
except Exception as e: except Exception as e:
logger.error(f"Error: {e}", exc_info=True) logger.error(f"Error: {e}", exc_info=True)
@ -503,7 +522,7 @@ class Bot:
text = text.strip() text = text.strip()
try: try:
await send_room_message(self.client, room_id, reply_message=text, await send_room_message(self.client, room_id, reply_message=text,
reply_to_event_id="", sender_id=sender_id, user_message=raw_user_message) reply_to_event_id="", sender_id=sender_id, user_message=raw_user_message, markdown_formatted=self.markdown_formatted)
except Exception as e: except Exception as e:
logger.error(f"Error: {e}", exc_info=True) logger.error(f"Error: {e}", exc_info=True)
@ -520,7 +539,7 @@ class Bot:
text = text.strip() text = text.strip()
try: try:
await send_room_message(self.client, room_id, reply_message=text, await send_room_message(self.client, room_id, reply_message=text,
reply_to_event_id="", sender_id=sender_id, user_message=raw_user_message) reply_to_event_id="", sender_id=sender_id, user_message=raw_user_message, markdown_formatted=self.markdown_formatted)
except Exception as e: except Exception as e:
logger.error(f"Error: {e}", exc_info=True) logger.error(f"Error: {e}", exc_info=True)

View file

@ -8,5 +8,6 @@
"bing_api_endpoint": "http://api:3000/conversation", "bing_api_endpoint": "http://api:3000/conversation",
"jailbreakEnabled": true, "jailbreakEnabled": true,
"access_token": "xxxxxxx", "access_token": "xxxxxxx",
"bing_auth_cookie": "xxxxxxxxxxx" "bing_auth_cookie": "xxxxxxxxxxx",
"markdown_formatted": true
} }

View file

@ -22,6 +22,7 @@ async def main():
access_token=config.get('access_token'), access_token=config.get('access_token'),
jailbreakEnabled=config.get('jailbreakEnabled'), jailbreakEnabled=config.get('jailbreakEnabled'),
bing_auth_cookie=config.get('bing_auth_cookie'), bing_auth_cookie=config.get('bing_auth_cookie'),
markdown_formatted=config.get('markdown_formatted'),
) )
else: else:
@ -35,6 +36,7 @@ async def main():
access_token=os.environ.get("ACCESS_TOKEN"), access_token=os.environ.get("ACCESS_TOKEN"),
jailbreakEnabled=os.environ.get("JAILBREAKENABLED", "false").lower() in ('true', '1', 't'), jailbreakEnabled=os.environ.get("JAILBREAKENABLED", "false").lower() in ('true', '1', 't'),
bing_auth_cookie=os.environ.get("BING_AUTH_COOKIE"), bing_auth_cookie=os.environ.get("BING_AUTH_COOKIE"),
markdown_formatted=os.environ.get("MARKDOWN_FORMATTED", "false").lower() in ('true', '1', 't'),
) )
await matrix_bot.login() await matrix_bot.login()

View file

@ -1,13 +1,31 @@
from nio import AsyncClient from nio import AsyncClient
import re
import markdown
async def send_room_message(client: AsyncClient, async def send_room_message(client: AsyncClient,
room_id: str, room_id: str,
reply_message: str, reply_message: str,
sender_id: str = '', sender_id: str = '',
user_message: str = '', user_message: str = '',
reply_to_event_id: str = '') -> None: reply_to_event_id: str = '',
markdown_formatted: bool = False) -> None:
NORMAL_BODY = content = {"msgtype": "m.text", "body": reply_message, }
if reply_to_event_id == '': if reply_to_event_id == '':
content = {"msgtype": "m.text", "body": reply_message, } if markdown_formatted:
# only format message contains multiline codes
if re.search(r"```", reply_message) is not None:
content = {
"msgtype": "m.text",
"body": reply_message,
"format": "org.matrix.custom.html",
"formatted_body": markdown.markdown(reply_message, extensions=['nl2br', 'tables', 'fenced_code'])
}
else:
content = NORMAL_BODY
else:
content = NORMAL_BODY
else: else:
body = r'> <' + sender_id + r'> ' + user_message + r'\n\n' + reply_message body = r'> <' + sender_id + r'> ' + user_message + r'\n\n' + reply_message
format = r'org.matrix.custom.html' format = r'org.matrix.custom.html'
@ -15,7 +33,7 @@ async def send_room_message(client: AsyncClient,
+ r'">In reply to</a> <a href="https://matrix.to/#/' + sender_id + r'">' + sender_id \ + r'">In reply to</a> <a href="https://matrix.to/#/' + sender_id + r'">' + sender_id \
+ r'</a><br>' + user_message + r'</blockquote></mx-reply>' + reply_message + r'</a><br>' + user_message + r'</blockquote></mx-reply>' + reply_message
content={"msgtype": "m.text", "body": body, "format": format, "formatted_body": formatted_body, content = {"msgtype": "m.text", "body": body, "format": format, "formatted_body": formatted_body,
"m.relates_to": {"m.in_reply_to": {"event_id": reply_to_event_id}}, } "m.relates_to": {"m.in_reply_to": {"event_id": reply_to_event_id}}, }
await client.room_send( await client.room_send(
room_id, room_id,