修复已知bug

This commit is contained in:
EillesWan 2024-11-30 18:03:50 +08:00
parent a888442311
commit 4999ed5294
3 changed files with 78 additions and 17 deletions

View File

@ -234,15 +234,28 @@ async def send_markdown(msg: str):
人工智能给出的回答一般不会包含 HTML 嵌入其中但是包含图片或者 LaTeX 公式代码块都很正常 人工智能给出的回答一般不会包含 HTML 嵌入其中但是包含图片或者 LaTeX 公式代码块都很正常
这个函数会把这些都以图片形式嵌入消息体 这个函数会把这些都以图片形式嵌入消息体
""" """
if not IMG_TAG_PATTERN.search(msg): # 没有图片标签
await UniMessage(msg).send(reply_to=True)
return
result_msg = UniMessage() result_msg = UniMessage()
code_blank_uuid_map = [ code_blank_uuid_map = [
(uuid.uuid4().hex, cbp.group()) for cbp in CODE_BLOCK_PATTERN.finditer(msg) (uuid.uuid4().hex, cbp.group()) for cbp in CODE_BLOCK_PATTERN.finditer(msg)
] ]
last_tag_index = 0
# 代码块渲染麻烦,先不处理 # 代码块渲染麻烦,先不处理
for rep, torep in code_blank_uuid_map: for rep, torep in code_blank_uuid_map:
msg = msg.replace(torep, rep) msg = msg.replace(torep, rep)
# for to_rep in CODE_SINGLE_PATTERN.finditer(msg):
# code_blank_uuid_map.append((rep := uuid.uuid4().hex, to_rep.group()))
# msg = msg.replace(to_rep.group(), rep)
print("#####################\n", msg, "\n\n")
# 插入图片 # 插入图片
for each_img_tag in IMG_TAG_PATTERN.finditer(msg): for each_img_tag in IMG_TAG_PATTERN.finditer(msg):
img_tag = await get_back_uuidcodeblock( img_tag = await get_back_uuidcodeblock(
@ -254,15 +267,29 @@ async def send_markdown(msg: str):
result_msg.append( result_msg.append(
TextMsg( TextMsg(
await get_back_uuidcodeblock( await get_back_uuidcodeblock(
msg[: msg.find(img_tag)], code_blank_uuid_map msg[last_tag_index : msg.find(img_tag)], code_blank_uuid_map
) )
) )
) )
result_msg.append(ImageMsg(url=image_url, name=image_description + ".png")) last_tag_index = msg.find(img_tag) + len(img_tag)
if image_ := await get_image_raw_and_type(image_url):
result_msg.append(
ImageMsg(
raw=image_[0], mimetype=image_[1], name=image_description + ".png"
)
)
result_msg.append(TextMsg("{}".format(image_description))) result_msg.append(TextMsg("{}".format(image_description)))
else:
result_msg.append(TextMsg(img_tag))
result_msg.append(
TextMsg(await get_back_uuidcodeblock(msg[last_tag_index:], code_blank_uuid_map))
)
await result_msg.send(reply_to=True) await result_msg.send(reply_to=True)

View File

@ -37,7 +37,7 @@ https://github.com/LiteyukiStudio/marshoai-melo"""
# 正则匹配代码块 # 正则匹配代码块
CODE_BLOCK_PATTERN = re.compile( CODE_BLOCK_PATTERN = re.compile(
r"```(.*?)```|`(.*?)`", r"```(.*?)```|`(.*?)`", re.DOTALL
) )
# 正则匹配完整图片标签字段 # 正则匹配完整图片标签字段
IMG_TAG_PATTERN = re.compile(r"!\[[^\]]*\]\([^()]*\)") IMG_TAG_PATTERN = re.compile(r"!\[[^\]]*\]\([^()]*\)")
@ -47,5 +47,5 @@ IMG_TAG_PATTERN = re.compile(r"!\[[^\]]*\]\([^()]*\)")
# INTAG_TEXT_PATTERN = re.compile(r'!\[([^\]]*)\]') # INTAG_TEXT_PATTERN = re.compile(r'!\[([^\]]*)\]')
# 正则匹配 LaTeX 公式内容 # 正则匹配 LaTeX 公式内容
LATEX_PATTERN = re.compile( LATEX_PATTERN = re.compile(
r"\\begin\{equation\}(.*?)\\\end\{equation\}|(?<!\$)(\$(.*?)\$|\$\$(.*?)\$\$|\\\[(.*?)\\\]|\\\[.*?\\\]|\\\((.*?)\\\))", r"\\begin\{equation\}(.*?)\\end\{equation\}|(?<!\$)(\$(.*?)\$|\$\$(.*?)\$\$|\\\[(.*?)\\\]|\\\[.*?\\\]|\\\((.*?)\\\))",
) )

View File

@ -2,7 +2,7 @@ import base64
import mimetypes import mimetypes
import os import os
import json import json
from typing import Any from typing import Any, Optional
import httpx import httpx
import nonebot_plugin_localstore as store import nonebot_plugin_localstore as store
@ -16,31 +16,65 @@ nickname_json = None # 记录昵称
praises_json = None # 记录夸赞名单 praises_json = None # 记录夸赞名单
loaded_target_list = [] # 记录已恢复备份的上下文的列表 loaded_target_list = [] # 记录已恢复备份的上下文的列表
async def get_image_b64(url):
# noinspection LongLine # noinspection LongLine
headers = { chromium_headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
} }
async def get_image_raw_and_type(
url: str, timeout: int = 10
) -> Optional[tuple[bytes, str]]:
"""
获取图片的二进制数据
参数:
url: str 图片链接
timeout: int 超时时间
return:
tuple[bytes, str]: 图片二进制数据, 图片MIME格式
"""
async with httpx.AsyncClient() as client: async with httpx.AsyncClient() as client:
response = await client.get(url, headers=headers) response = await client.get(url, headers=chromium_headers, timeout=timeout)
if response.status_code == 200: if response.status_code == 200:
# 获取图片数据 # 获取图片数据
image_data = response.content
content_type = response.headers.get("Content-Type") content_type = response.headers.get("Content-Type")
if not content_type: if not content_type:
content_type = mimetypes.guess_type(url)[0] content_type = mimetypes.guess_type(url)[0]
# image_format = content_type.split("/")[1] if content_type else "jpeg" # image_format = content_type.split("/")[1] if content_type else "jpeg"
base64_image = base64.b64encode(image_data).decode("utf-8") return response.content, str(content_type)
data_url = f"data:{content_type};base64,{base64_image}" else:
return None
async def get_image_b64(url: str, timeout: int = 10) -> Optional[str]:
"""
获取图片的base64编码
参数:
url: 图片链接
timeout: 超时时间
return: 图片base64编码
"""
if data_type := await get_image_raw_and_type(url, timeout):
# image_format = content_type.split("/")[1] if content_type else "jpeg"
base64_image = base64.b64encode(data_type[0]).decode("utf-8")
data_url = "data:{};base64,{}".format(data_type[1], base64_image)
return data_url return data_url
else: else:
return None return None
async def make_chat( async def make_chat(
client: ChatCompletionsClient, msg: list, model_name: str, tools: list = None client: ChatCompletionsClient,
msg: list,
model_name: str,
tools: Optional[list] = None,
): ):
"""调用ai获取回复 """调用ai获取回复