Merge branch 'dev' of https://github.com/Mai-with-u/MaiBot into dev
This commit is contained in:
@@ -28,7 +28,7 @@ class ExpressionReflector:
|
|||||||
try:
|
try:
|
||||||
logger.debug(f"[Expression Reflection] 开始检查是否需要提问 (stream_id: {self.chat_id})")
|
logger.debug(f"[Expression Reflection] 开始检查是否需要提问 (stream_id: {self.chat_id})")
|
||||||
|
|
||||||
if not global_config.expression.expression_self_reflect:
|
if not global_config.expression.expression_manual_reflect:
|
||||||
logger.debug("[Expression Reflection] 表达反思功能未启用,跳过")
|
logger.debug("[Expression Reflection] 表达反思功能未启用,跳过")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|||||||
@@ -545,9 +545,9 @@ class HeartFChatting:
|
|||||||
new_message_count = message_api.count_new_messages(
|
new_message_count = message_api.count_new_messages(
|
||||||
chat_id=self.chat_stream.stream_id, start_time=self.last_read_time, end_time=time.time()
|
chat_id=self.chat_stream.stream_id, start_time=self.last_read_time, end_time=time.time()
|
||||||
)
|
)
|
||||||
need_reply = new_message_count >= random.randint(2, 3)
|
need_reply = new_message_count >= random.randint(2, 3) or time.time() - self.last_read_time > 90
|
||||||
if need_reply:
|
if need_reply:
|
||||||
logger.info(f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,使用引用回复")
|
logger.info(f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,使用引用回复,或者上次回复时间超过90秒")
|
||||||
|
|
||||||
reply_text = ""
|
reply_text = ""
|
||||||
first_replied = False
|
first_replied = False
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import time
|
import time
|
||||||
|
import asyncio
|
||||||
import urllib3
|
import urllib3
|
||||||
|
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
@@ -20,6 +21,9 @@ logger = get_logger("chat_message")
|
|||||||
# 禁用SSL警告
|
# 禁用SSL警告
|
||||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# VLM 处理并发限制(避免同时处理太多图片导致卡死)
|
||||||
|
_vlm_semaphore = asyncio.Semaphore(3)
|
||||||
|
|
||||||
# 这个类是消息数据类,用于存储和管理消息数据。
|
# 这个类是消息数据类,用于存储和管理消息数据。
|
||||||
# 它定义了消息的属性,包括群组ID、用户ID、消息ID、原始消息内容、纯文本内容和时间戳。
|
# 它定义了消息的属性,包括群组ID、用户ID、消息ID、原始消息内容、纯文本内容和时间戳。
|
||||||
# 它还定义了两个辅助属性:keywords用于提取消息的关键词,is_plain_text用于判断消息是否为纯文本。
|
# 它还定义了两个辅助属性:keywords用于提取消息的关键词,is_plain_text用于判断消息是否为纯文本。
|
||||||
@@ -73,20 +77,35 @@ class Message(MessageBase):
|
|||||||
str: 处理后的文本
|
str: 处理后的文本
|
||||||
"""
|
"""
|
||||||
if segment.type == "seglist":
|
if segment.type == "seglist":
|
||||||
# 处理消息段列表
|
# 处理消息段列表 - 使用并行处理提升性能
|
||||||
|
tasks = [self._process_message_segments(seg) for seg in segment.data] # type: ignore
|
||||||
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||||
segments_text = []
|
segments_text = []
|
||||||
for seg in segment.data:
|
for result in results:
|
||||||
processed = await self._process_message_segments(seg) # type: ignore
|
if isinstance(result, Exception):
|
||||||
if processed:
|
logger.error(f"处理消息段时出错: {result}")
|
||||||
segments_text.append(processed)
|
continue
|
||||||
|
if result:
|
||||||
|
segments_text.append(result)
|
||||||
return " ".join(segments_text)
|
return " ".join(segments_text)
|
||||||
elif segment.type == "forward":
|
elif segment.type == "forward":
|
||||||
segments_text = []
|
# 处理转发消息 - 使用并行处理
|
||||||
for node_dict in segment.data:
|
async def process_forward_node(node_dict):
|
||||||
message = MessageBase.from_dict(node_dict) # type: ignore
|
message = MessageBase.from_dict(node_dict) # type: ignore
|
||||||
processed_text = await self._process_message_segments(message.message_segment)
|
processed_text = await self._process_message_segments(message.message_segment)
|
||||||
if processed_text:
|
if processed_text:
|
||||||
segments_text.append(f"{global_config.bot.nickname}: {processed_text}")
|
return f"{global_config.bot.nickname}: {processed_text}"
|
||||||
|
return None
|
||||||
|
|
||||||
|
tasks = [process_forward_node(node_dict) for node_dict in segment.data]
|
||||||
|
results = await asyncio.gather(*tasks, return_exceptions=True)
|
||||||
|
segments_text = []
|
||||||
|
for result in results:
|
||||||
|
if isinstance(result, Exception):
|
||||||
|
logger.error(f"处理转发节点时出错: {result}")
|
||||||
|
continue
|
||||||
|
if result:
|
||||||
|
segments_text.append(result)
|
||||||
return "[合并消息]: " + "\n-- ".join(segments_text)
|
return "[合并消息]: " + "\n-- ".join(segments_text)
|
||||||
else:
|
else:
|
||||||
# 处理单个消息段
|
# 处理单个消息段
|
||||||
@@ -173,8 +192,9 @@ class MessageRecv(Message):
|
|||||||
self.is_picid = True
|
self.is_picid = True
|
||||||
self.is_emoji = False
|
self.is_emoji = False
|
||||||
image_manager = get_image_manager()
|
image_manager = get_image_manager()
|
||||||
# print(f"segment.data: {segment.data}")
|
# 使用 semaphore 限制 VLM 并发,避免同时处理太多图片
|
||||||
_, processed_text = await image_manager.process_image(segment.data)
|
async with _vlm_semaphore:
|
||||||
|
_, processed_text = await image_manager.process_image(segment.data)
|
||||||
return processed_text
|
return processed_text
|
||||||
return "[发了一张图片,网卡了加载不出来]"
|
return "[发了一张图片,网卡了加载不出来]"
|
||||||
elif segment.type == "emoji":
|
elif segment.type == "emoji":
|
||||||
@@ -183,7 +203,9 @@ class MessageRecv(Message):
|
|||||||
self.is_picid = False
|
self.is_picid = False
|
||||||
self.is_voice = False
|
self.is_voice = False
|
||||||
if isinstance(segment.data, str):
|
if isinstance(segment.data, str):
|
||||||
return await get_image_manager().get_emoji_description(segment.data)
|
# 使用 semaphore 限制 VLM 并发
|
||||||
|
async with _vlm_semaphore:
|
||||||
|
return await get_image_manager().get_emoji_description(segment.data)
|
||||||
return "[发了一个表情包,网卡了加载不出来]"
|
return "[发了一个表情包,网卡了加载不出来]"
|
||||||
elif segment.type == "voice":
|
elif segment.type == "voice":
|
||||||
self.is_picid = False
|
self.is_picid = False
|
||||||
|
|||||||
@@ -50,7 +50,15 @@ class Server:
|
|||||||
async def run(self):
|
async def run(self):
|
||||||
"""启动服务器"""
|
"""启动服务器"""
|
||||||
# 禁用 uvicorn 默认日志和访问日志
|
# 禁用 uvicorn 默认日志和访问日志
|
||||||
config = Config(app=self.app, host=self._host, port=self._port, log_config=None, access_log=False)
|
# 设置 ws_max_size 为 100MB,支持大消息(如包含多张图片的转发消息)
|
||||||
|
config = Config(
|
||||||
|
app=self.app,
|
||||||
|
host=self._host,
|
||||||
|
port=self._port,
|
||||||
|
log_config=None,
|
||||||
|
access_log=False,
|
||||||
|
ws_max_size=104_857_600, # 100MB
|
||||||
|
)
|
||||||
self._server = UvicornServer(config=config)
|
self._server = UvicornServer(config=config)
|
||||||
try:
|
try:
|
||||||
await self._server.serve()
|
await self._server.serve()
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
1
webui/dist/assets/index-B50WYNXg.css
vendored
Normal file
1
webui/dist/assets/index-B50WYNXg.css
vendored
Normal file
File diff suppressed because one or more lines are too long
94
webui/dist/assets/index-D90_5BXS.js
vendored
Normal file
94
webui/dist/assets/index-D90_5BXS.js
vendored
Normal file
File diff suppressed because one or more lines are too long
91
webui/dist/assets/index-DC6giT2e.js
vendored
91
webui/dist/assets/index-DC6giT2e.js
vendored
File diff suppressed because one or more lines are too long
1
webui/dist/assets/index-DseBW7cm.css
vendored
1
webui/dist/assets/index-DseBW7cm.css
vendored
File diff suppressed because one or more lines are too long
BIN
webui/dist/fonts/JetBrainsMono-Medium.ttf
vendored
Normal file
BIN
webui/dist/fonts/JetBrainsMono-Medium.ttf
vendored
Normal file
Binary file not shown.
6
webui/dist/index.html
vendored
6
webui/dist/index.html
vendored
@@ -11,21 +11,21 @@
|
|||||||
<link rel="icon" type="image/x-icon" href="/maimai.ico" />
|
<link rel="icon" type="image/x-icon" href="/maimai.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>MaiBot Dashboard</title>
|
<title>MaiBot Dashboard</title>
|
||||||
<script type="module" crossorigin src="/assets/index-DC6giT2e.js"></script>
|
<script type="module" crossorigin src="/assets/index-D90_5BXS.js"></script>
|
||||||
<link rel="modulepreload" crossorigin href="/assets/react-vendor-BmxF9s7Q.js">
|
<link rel="modulepreload" crossorigin href="/assets/react-vendor-BmxF9s7Q.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/router-9vIXuQkh.js">
|
<link rel="modulepreload" crossorigin href="/assets/router-9vIXuQkh.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/utils-BqoaXoQ1.js">
|
<link rel="modulepreload" crossorigin href="/assets/utils-BqoaXoQ1.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/radix-core-DyJi0yyw.js">
|
<link rel="modulepreload" crossorigin href="/assets/radix-core-DyJi0yyw.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/radix-extra-DmmnfeQE.js">
|
<link rel="modulepreload" crossorigin href="/assets/radix-extra-DmmnfeQE.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/charts-simvewUa.js">
|
<link rel="modulepreload" crossorigin href="/assets/charts-simvewUa.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/icons-9Z4kBNLK.js">
|
<link rel="modulepreload" crossorigin href="/assets/icons-CmIU8FzD.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/codemirror-TZqPU532.js">
|
<link rel="modulepreload" crossorigin href="/assets/codemirror-TZqPU532.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/dnd-BiPfFtVp.js">
|
<link rel="modulepreload" crossorigin href="/assets/dnd-BiPfFtVp.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/misc-CJqnlRwD.js">
|
<link rel="modulepreload" crossorigin href="/assets/misc-CJqnlRwD.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/reactflow-DtsZHOR4.js">
|
<link rel="modulepreload" crossorigin href="/assets/reactflow-DtsZHOR4.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/uppy-DFP_VzYR.js">
|
<link rel="modulepreload" crossorigin href="/assets/uppy-DFP_VzYR.js">
|
||||||
<link rel="modulepreload" crossorigin href="/assets/markdown-CKA5gBQ9.js">
|
<link rel="modulepreload" crossorigin href="/assets/markdown-CKA5gBQ9.js">
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DseBW7cm.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-B50WYNXg.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" class="notranslate"></div>
|
<div id="root" class="notranslate"></div>
|
||||||
|
|||||||
Reference in New Issue
Block a user