mirror of
https://github.com/LiteyukiStudio/nonebot-plugin-marshoai.git
synced 2025-02-07 02:46:10 +08:00
✨ 添加提取思维链,处理消息对象的函数,改善兼容性
This commit is contained in:
parent
887bf808a7
commit
42bed6aeca
@ -6,7 +6,6 @@ import openai
|
||||
from arclet.alconna import Alconna, AllParam, Args
|
||||
from azure.ai.inference.models import (
|
||||
AssistantMessage,
|
||||
ChatCompletionsToolCall,
|
||||
CompletionsFinishReason,
|
||||
ImageContentItem,
|
||||
ImageUrl,
|
||||
@ -22,7 +21,6 @@ from nonebot.permission import SUPERUSER
|
||||
from nonebot.rule import Rule, to_me
|
||||
from nonebot.typing import T_State
|
||||
from nonebot_plugin_alconna import MsgTarget, UniMessage, UniMsg, on_alconna
|
||||
from openai import AsyncOpenAI
|
||||
|
||||
from .hooks import *
|
||||
from .instances import *
|
||||
@ -287,7 +285,7 @@ async def marsho(
|
||||
tools_lists = tools.tools_list + list(
|
||||
map(lambda v: v.data(), get_function_calls().values())
|
||||
)
|
||||
logger.debug(f"正在获取回答,模型:{model_name}")
|
||||
logger.info(f"正在获取回答,模型:{model_name}")
|
||||
response = await make_chat_openai(
|
||||
client=client,
|
||||
model_name=model_name,
|
||||
@ -306,25 +304,26 @@ async def marsho(
|
||||
context.append(
|
||||
UserMessage(content=usermsg).as_dict(), target.id, target.private # type: ignore
|
||||
)
|
||||
choice_msg_dict = choice.message.to_dict()
|
||||
if "reasoning_content" in choice_msg_dict:
|
||||
if config.marshoai_send_thinking:
|
||||
await UniMessage(
|
||||
"思维链:\n" + choice_msg_dict["reasoning_content"]
|
||||
).send()
|
||||
del choice_msg_dict["reasoning_content"]
|
||||
context.append(choice_msg_dict, target.id, target.private)
|
||||
|
||||
##### DeepSeek-R1 兼容部分 #####
|
||||
choice_msg_content, choice_msg_thinking, choice_msg_after = (
|
||||
extract_content_and_think(choice.message)
|
||||
)
|
||||
if choice_msg_thinking and config.marshoai_send_thinking:
|
||||
await UniMessage("思维链:\n" + choice_msg_thinking).send()
|
||||
##### 兼容部分结束 #####
|
||||
|
||||
context.append(choice_msg_after.to_dict(), target.id, target.private)
|
||||
if [target.id, target.private] not in target_list:
|
||||
target_list.append([target.id, target.private])
|
||||
|
||||
# 对话成功发送消息
|
||||
if config.marshoai_enable_richtext_parse:
|
||||
await (await parse_richtext(str(choice.message.content))).send(
|
||||
await (await parse_richtext(str(choice_msg_content))).send(
|
||||
reply_to=True
|
||||
)
|
||||
else:
|
||||
await UniMessage(str(choice.message.content)).send(reply_to=True)
|
||||
await UniMessage(str(choice_msg_content)).send(reply_to=True)
|
||||
elif choice.finish_reason == CompletionsFinishReason.CONTENT_FILTERED:
|
||||
|
||||
# 对话失败,消息过滤
|
||||
@ -467,9 +466,8 @@ with contextlib.suppress(ImportError): # 优化先不做()
|
||||
)
|
||||
choice = response.choices[0]
|
||||
if choice.finish_reason == CompletionsFinishReason.STOPPED:
|
||||
await UniMessage(" " + str(choice.message.content)).send(
|
||||
at_sender=True
|
||||
)
|
||||
content = extract_content_and_think(choice.message)[0]
|
||||
await UniMessage(" " + str(content)).send(at_sender=True)
|
||||
except Exception as e:
|
||||
await UniMessage(str(e) + suggest_solution(str(e))).send()
|
||||
traceback.print_exc()
|
||||
|
@ -1,6 +1,7 @@
|
||||
import base64
|
||||
import json
|
||||
import mimetypes
|
||||
import re
|
||||
import uuid
|
||||
from typing import Any, Optional
|
||||
|
||||
@ -15,6 +16,7 @@ from nonebot_plugin_alconna import Image as ImageMsg
|
||||
from nonebot_plugin_alconna import Text as TextMsg
|
||||
from nonebot_plugin_alconna import UniMessage
|
||||
from openai import AsyncOpenAI, NotGiven
|
||||
from openai.types.chat import ChatCompletionMessage
|
||||
from zhDateTime import DateTime
|
||||
|
||||
from .config import config
|
||||
@ -34,7 +36,7 @@ if config.marshoai_enable_time_prompt:
|
||||
|
||||
|
||||
# noinspection LongLine
|
||||
_chromium_headers = {
|
||||
_browser_headers = {
|
||||
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0"
|
||||
}
|
||||
"""
|
||||
@ -47,7 +49,7 @@ _praises_init_data = {
|
||||
"like": [
|
||||
{
|
||||
"name": "Asankilp",
|
||||
"advantages": "赋予了Marsho猫娘人格,使用手机,在vim与vscode的加持下为Marsho写了许多代码,使Marsho更加可爱",
|
||||
"advantages": "赋予了Marsho猫娘人格,在vim与vscode的加持下为Marsho写了许多代码,使Marsho更加可爱",
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -71,7 +73,7 @@ async def get_image_raw_and_type(
|
||||
"""
|
||||
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.get(url, headers=_chromium_headers, timeout=timeout)
|
||||
response = await client.get(url, headers=_browser_headers, timeout=timeout)
|
||||
if response.status_code == 200:
|
||||
# 获取图片数据
|
||||
content_type = response.headers.get("Content-Type")
|
||||
@ -180,7 +182,7 @@ async def refresh_praises_json():
|
||||
praises_json = data
|
||||
|
||||
|
||||
def build_praises():
|
||||
def build_praises() -> str:
|
||||
praises = get_praises()
|
||||
result = ["你喜欢以下几个人物,他们有各自的优点:"]
|
||||
for item in praises["like"]:
|
||||
@ -461,3 +463,41 @@ if config.marshoai_enable_richtext_parse:
|
||||
"""
|
||||
Mulan PSL v2 协议授权部分结束
|
||||
"""
|
||||
|
||||
|
||||
def extract_content_and_think(
|
||||
message: ChatCompletionMessage,
|
||||
) -> tuple[str, str | None, ChatCompletionMessage]:
|
||||
"""
|
||||
处理 API 返回的消息对象,提取其中的内容和思维链,并返回处理后的消息,思维链,消息对象。
|
||||
|
||||
Args:
|
||||
message (ChatCompletionMessage): API 返回的消息对象。
|
||||
Returns:
|
||||
|
||||
- content (str): 提取出的消息内容。
|
||||
|
||||
- thinking (str | None): 提取出的思维链,如果没有则为 None。
|
||||
|
||||
- message (ChatCompletionMessage): 移除了思维链的消息对象。
|
||||
|
||||
本函数参考自 [nonebot-plugin-deepseek](https://github.com/KomoriDev/nonebot-plugin-deepseek)
|
||||
"""
|
||||
try:
|
||||
thinking = message.reasoning_content # type: ignore
|
||||
except AttributeError:
|
||||
thinking = None
|
||||
if thinking:
|
||||
delattr(message, "reasoning_content")
|
||||
else:
|
||||
think_blocks = re.findall(
|
||||
r"<think>(.*?)</think>", message.content or "", flags=re.DOTALL
|
||||
)
|
||||
thinking = "\n".join([block.strip() for block in think_blocks if block.strip()])
|
||||
|
||||
content = re.sub(
|
||||
r"<think>.*?</think>", "", message.content or "", flags=re.DOTALL
|
||||
).strip()
|
||||
message.content = content
|
||||
|
||||
return content, thinking, message
|
||||
|
Loading…
x
Reference in New Issue
Block a user