From 130a0fdb3187147974e87e9b698142bdb849811a Mon Sep 17 00:00:00 2001 From: tt-P607 <68868379+tt-P607@users.noreply.github.com> Date: Sun, 9 Nov 2025 00:50:23 +0800 Subject: [PATCH] =?UTF-8?q?refactor(core):=20=E7=AE=80=E5=8C=96=E5=9B=9E?= =?UTF-8?q?=E5=A4=8D=E6=B8=85=E7=90=86=E5=B9=B6=E5=8A=A0=E5=BC=BA=20API=20?= =?UTF-8?q?=E8=B0=83=E7=94=A8=E6=AD=A4=E6=AC=A1=E6=8F=90=E4=BA=A4=E5=BD=BB?= =?UTF-8?q?=E5=BA=95=E9=87=8D=E6=9E=84=E4=BA=86=E5=9B=9E=E5=A4=8D=E6=B8=85?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BB=A5=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E5=8F=AF=E7=BB=B4=E6=8A=A4=E6=80=A7=EF=BC=8C=E5=B9=B6=E5=9C=A8?= =?UTF-8?q?=E5=8F=91=E9=80=81=20API=20=E4=B8=AD=E5=BC=95=E5=85=A5=E4=BA=86?= =?UTF-8?q?=E5=A4=9A=E9=A1=B9=E9=98=B2=E5=BE=A1=E6=80=A7=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E9=98=B2=E6=AD=A2=E5=B8=B8=E8=A7=81=E7=9A=84?= =?UTF-8?q?=E8=BF=90=E8=A1=8C=E6=97=B6=E9=94=99=E8=AF=AF=E3=80=82=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E5=B0=86=E5=A4=8D=E6=9D=82=E7=9A=84=E8=BF=AD=E4=BB=A3?= =?UTF-8?q?=E6=B8=85=E7=90=86=E7=AE=97=E6=B3=95=E6=9B=BF=E6=8D=A2=E4=B8=BA?= =?UTF-8?q?=E5=8D=95=E4=B8=80=E4=B8=94=E6=9B=B4=E9=AB=98=E6=95=88=E7=9A=84?= =?UTF-8?q?=E6=AD=A3=E5=88=99=E8=A1=A8=E8=BE=BE=E5=BC=8F=EF=BC=8C=E5=9B=9E?= =?UTF-8?q?=E5=A4=8D=E7=94=9F=E6=88=90=E8=BF=87=E7=A8=8B=E5=BE=97=E5=88=B0?= =?UTF-8?q?=E4=BA=86=E7=AE=80=E5=8C=96=E3=80=82=E8=BF=99=E4=B8=8D=E4=BB=85?= =?UTF-8?q?=E6=8F=90=E9=AB=98=E4=BA=86=E5=8E=BB=E9=99=A4=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E7=94=9F=E6=88=90=E7=9A=84=E5=A4=B4=E4=BF=A1=E6=81=AF=E7=9A=84?= =?UTF-8?q?=E5=8F=AF=E9=9D=A0=E6=80=A7=EF=BC=8C=E8=BF=98=E6=98=BE=E8=91=97?= =?UTF-8?q?=E9=99=8D=E4=BD=8E=E4=BA=86=E4=BB=A3=E7=A0=81=E5=A4=8D=E6=9D=82?= =?UTF-8?q?=E6=80=A7=E3=80=82=E5=9C=A8=E5=8F=91=E9=80=81=20API=20=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E5=AE=9E=E7=8E=B0=E4=BA=86=E5=A4=9A=E4=B8=AA=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E6=8E=AA=E6=96=BD=EF=BC=9A-=20=E4=BF=AE=E6=AD=A3?= =?UTF-8?q?=E4=BA=86=E5=BC=82=E6=AD=A5=E5=A4=84=E7=90=86=E9=94=99=E8=AF=AF?= =?UTF-8?q?=EF=BC=8C=E9=80=9A=E8=BF=87=E7=A7=BB=E9=99=A4=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=AD=97=E5=85=B8=E6=93=8D=E4=BD=9C=E4=B8=8A=E6=97=A0=E6=95=88?= =?UTF-8?q?=E7=9A=84=20`await`=EF=BC=8C=E9=98=B2=E6=AD=A2=E5=87=BA?= =?UTF-8?q?=E7=8E=B0=20`TypeError`=E3=80=82-=20=E6=B7=BB=E5=8A=A0=E4=BA=86?= =?UTF-8?q?=E9=A2=84=E6=A3=80=E9=AA=8C=E8=AF=81=EF=BC=8C=E4=BB=A5=E7=A1=AE?= =?UTF-8?q?=E4=BF=9D=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0=E6=9C=89=E5=AE=9A?= =?UTF-8?q?=E4=B9=89=E7=9A=84=E7=9B=AE=E6=A0=87=EF=BC=8C=E5=B9=B6=E4=B8=94?= =?UTF-8?q?=E4=B8=B4=E6=97=B6=E6=B5=81=E6=8C=87=E5=AE=9A=E4=BA=86=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E3=80=82-=20=E7=8E=B0=E5=9C=A8=E4=B8=80=E8=87=B4?= =?UTF-8?q?=E5=B0=86=E6=9C=BA=E5=99=A8=E4=BA=BA=E7=94=A8=E6=88=B7=20ID=20?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E4=B8=BA=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E6=B6=88=E9=99=A4=E6=BD=9C=E5=9C=A8=E7=9A=84=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E7=9B=B8=E5=85=B3=E4=B8=8D=E4=B8=80=E8=87=B4=E3=80=82?= =?UTF-8?q?=E6=9C=80=E5=90=8E=EF=BC=8C=E4=B8=BA=E4=BA=86=E6=B8=85=E6=99=B0?= =?UTF-8?q?=E8=B5=B7=E8=A7=81=EF=BC=8C=E6=9C=BA=E5=99=A8=E4=BA=BA=E7=9A=84?= =?UTF-8?q?=E8=A1=8C=E4=B8=BA=E5=8E=9F=E5=88=99=E6=9C=AF=E8=AF=AD=E4=B9=9F?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E4=BA=86=E8=B0=83=E6=95=B4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/chat/replyer/default_generator.py | 39 +++++++-------------------- src/plugin_system/apis/send_api.py | 18 ++++++++----- template/bot_config_template.toml | 4 +-- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index 194f37c13..d69cb469a 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -1411,10 +1411,10 @@ class DefaultReplyer: safety_guidelines_block = "" if safety_guidelines: guidelines_text = "\n".join(f"{i + 1}. {line}" for i, line in enumerate(safety_guidelines)) - safety_guidelines_block = f"""### 安全与互动底线 + safety_guidelines_block = f"""### 互动规则 在任何情况下,你都必须遵守以下由你的设定者为你定义的原则: {guidelines_text} -如果遇到违反上述原则的请求,请在保持你核心人设的同时,巧妙地拒绝或转移话题。 +如果遇到违反上述原则的请求,请在保持你核心人设的同时,以合适的方式进行回应。 """ if sender and target: @@ -1740,35 +1740,16 @@ class DefaultReplyer: if content: # 移除 [SPLIT] 标记,防止消息被分割 - cleaned_content = content.replace("[SPLIT]", "") + content = content.replace("[SPLIT]", "") + - # 循环移除,以处理模型可能生成的嵌套回复头/尾 - # 使用更健壮的正则表达式,通过非贪婪匹配和向后查找来定位真正的消息内容 - pattern = re.compile(r"^\s*\[回复<.+?>\s*(?:的消息)?:(?P.*)\](?:,?说:)?\s*$", re.DOTALL) + aggressive_pattern = re.compile(r'\[\s*回复\s*<.+?>.*?\]', re.DOTALL) + original_content_for_aggresive_filter = content + cleaned_content_by_aggresive_filter = aggressive_pattern.sub('', content).strip() - temp_content = cleaned_content - while True: - match = pattern.match(temp_content) - if match: - new_content = match.group("content").strip() - # 如果内容没有变化,说明可能无法进一步解析,退出循环 - if new_content == temp_content: - break - temp_content = new_content - else: - break # 没有匹配到,退出循环 - - # 在循环处理后,再使用 rsplit 来处理日志中观察到的特殊情况 - # 这可以作为处理复杂嵌套的最后一道防线 - final_split = temp_content.rsplit("],说:", 1) - if len(final_split) > 1: - final_content = final_split[1].strip() - else: - final_content = temp_content - - if final_content != content: - logger.debug(f"清理了模型生成的多余内容,原始内容: '{content}', 清理后: '{final_content}'") - content = final_content + if cleaned_content_by_aggresive_filter != original_content_for_aggresive_filter: + logger.warning(f"检测到并清理了模型生成的不规范回复格式。原始内容: '{original_content_for_aggresive_filter}', 清理后: '{cleaned_content_by_aggresive_filter}'") + content = cleaned_content_by_aggresive_filter logger.debug(f"replyer生成内容: {content}") return content, reasoning_content, model_name, tool_calls diff --git a/src/plugin_system/apis/send_api.py b/src/plugin_system/apis/send_api.py index 429be54c8..7214cd874 100644 --- a/src/plugin_system/apis/send_api.py +++ b/src/plugin_system/apis/send_api.py @@ -62,12 +62,15 @@ async def file_to_stream( } action = "" - if target_stream.group_info: + if target_stream.group_info and target_stream.group_info.group_id: action = "upload_group_file" params["group_id"] = target_stream.group_info.group_id - else: + elif target_stream.user_info and target_stream.user_info.user_id: action = "upload_private_file" params["user_id"] = target_stream.user_info.user_id + else: + logger.error(f"[SendAPI] 无法确定文件发送目标: {stream_id}") + return False response = await adapter_command_to_stream( action=action, @@ -173,10 +176,10 @@ async def wait_adapter_response(request_id: str, timeout: float = 30.0) -> dict: response = await asyncio.wait_for(future, timeout=timeout) return response except asyncio.TimeoutError: - await _adapter_response_pool.pop(request_id, None) + _adapter_response_pool.pop(request_id, None) return {"status": "error", "message": "timeout"} except Exception as e: - await _adapter_response_pool.pop(request_id, None) + _adapter_response_pool.pop(request_id, None) return {"status": "error", "message": str(e)} @@ -234,7 +237,7 @@ async def _send_to_target( # 构建机器人用户信息 bot_user_info = UserInfo( - user_id=global_config.bot.qq_account, + user_id=str(global_config.bot.qq_account), user_nickname=global_config.bot.nickname, platform=target_stream.platform, ) @@ -499,6 +502,9 @@ async def adapter_command_to_stream( logger.debug(f"[SendAPI] 创建临时虚拟聊天流: {stream_id}") # 创建临时的用户信息和聊天流 + if not platform: + logger.error("[SendAPI] 创建临时聊天流失败: platform 未提供") + return {"status": "error", "message": "platform 未提供"} temp_user_info = UserInfo(user_id="system", user_nickname="System", platform=platform) @@ -520,7 +526,7 @@ async def adapter_command_to_stream( # 构建机器人用户信息 bot_user_info = UserInfo( - user_id=global_config.bot.qq_account, + user_id=str(global_config.bot.qq_account), user_nickname=global_config.bot.nickname, platform=target_stream.platform, ) diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index e7862ac0c..54ce4508b 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -89,8 +89,8 @@ background_story = "" # 描述MoFox-Bot说话的表达风格,表达习惯,如要修改,可以酌情新增内容 reply_style = "回复可以简短一些。可以参考贴吧,知乎和微博的回复风格,回复不要浮夸,不要用夸张修辞,平淡一些。" -# 安全与互动底线 (Bot在任何情况下都必须遵守的原则) -# 你可以在这里定义Bot的行为红线,例如如何回应不恰当的问题。 +# 互动规则 (Bot在任何情况下都必须遵守的原则) +# 你可以在这里定义Bot在互动中的行为准则。 safety_guidelines = [ "拒绝任何包含骚扰、冒犯、暴力、色情或危险内容的请求。", "在拒绝时,请使用符合你人设的、坚定的语气。",