diff --git a/src/chat/chat_loop/heartFC_chat.py b/src/chat/chat_loop/heartFC_chat.py index 5a82e8390..48df4253c 100644 --- a/src/chat/chat_loop/heartFC_chat.py +++ b/src/chat/chat_loop/heartFC_chat.py @@ -21,9 +21,8 @@ from src.plugin_system.base.component_types import ActionInfo, ChatMode from src.plugin_system.apis import generator_api, send_api, message_api from src.chat.willing.willing_manager import get_willing_manager from src.chat.mai_thinking.mai_think import mai_thinking_manager -from maim_message.message_base import GroupInfo,UserInfo - -ENABLE_THINKING = False +from maim_message.message_base import GroupInfo +from src.mais4u.constant_s4u import ENABLE_THINKING ERROR_LOOP_INFO = { "loop_plan_info": { @@ -296,7 +295,8 @@ class HeartFChatting: logger.info(f"{self.log_prefix} 开始第{self._cycle_counter}次思考[模式:{self.loop_mode}]") - await self.send_typing() + if ENABLE_THINKING: + await self.send_typing() async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()): loop_start_time = time.time() @@ -366,11 +366,12 @@ class HeartFChatting: # 发送回复 (不再需要传入 chat) reply_text = await self._send_response(response_set, reply_to_str, loop_start_time,message_data) - await self.stop_typing() + if ENABLE_THINKING: + await self.stop_typing() await mai_thinking_manager.get_mai_think(self.stream_id).do_think_after_response(reply_text) diff --git a/src/chat/mai_thinking/mai_think.py b/src/chat/mai_thinking/mai_think.py index c438b32eb..867ba8bef 100644 --- a/src/chat/mai_thinking/mai_think.py +++ b/src/chat/mai_thinking/mai_think.py @@ -3,7 +3,7 @@ import time from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.llm_models.utils_model import LLMRequest from src.config.config import global_config -from src.chat.message_receive.message import MessageSending, MessageRecv, MessageRecvS4U +from src.chat.message_receive.message import MessageRecvS4U from src.mais4u.mais4u_chat.s4u_msg_processor import S4UMessageProcessor from src.mais4u.mais4u_chat.internal_manager import internal_manager from src.common.logger import get_logger diff --git a/src/mais4u/constant_s4u.py b/src/mais4u/constant_s4u.py new file mode 100644 index 000000000..7f3d6fadc --- /dev/null +++ b/src/mais4u/constant_s4u.py @@ -0,0 +1 @@ +ENABLE_THINKING = False \ No newline at end of file diff --git a/src/plugins/built_in/core_actions/plugin.py b/src/plugins/built_in/core_actions/plugin.py index 015189e2b..d01177a0a 100644 --- a/src/plugins/built_in/core_actions/plugin.py +++ b/src/plugins/built_in/core_actions/plugin.py @@ -5,15 +5,10 @@ 这是系统的内置插件,提供基础的聊天交互功能 """ -import random -import time from typing import List, Tuple, Type -import asyncio -import re -import traceback # 导入新插件系统 -from src.plugin_system import BasePlugin, register_plugin, BaseAction, ComponentInfo, ActionActivationType, ChatMode +from src.plugin_system import BasePlugin, register_plugin, ComponentInfo, ActionActivationType from src.plugin_system.base.config_types import ConfigField from src.config.config import global_config @@ -21,140 +16,12 @@ from src.config.config import global_config from src.common.logger import get_logger # 导入API模块 - 标准Python包方式 -from src.plugin_system.apis import generator_api, message_api from src.plugins.built_in.core_actions.no_reply import NoReplyAction from src.plugins.built_in.core_actions.emoji import EmojiAction -from src.person_info.person_info import get_person_info_manager -from src.chat.mai_thinking.mai_think import mai_thinking_manager +from src.plugins.built_in.core_actions.reply import ReplyAction logger = get_logger("core_actions") -# 常量定义 -WAITING_TIME_THRESHOLD = 1200 # 等待新消息时间阈值,单位秒 - -ENABLE_THINKING = False - -class ReplyAction(BaseAction): - """回复动作 - 参与聊天回复""" - - # 激活设置 - focus_activation_type = ActionActivationType.NEVER - normal_activation_type = ActionActivationType.NEVER - mode_enable = ChatMode.FOCUS - parallel_action = False - - # 动作基本信息 - action_name = "reply" - action_description = "参与聊天回复,发送文本进行表达" - - # 动作参数定义 - action_parameters = {} - - # 动作使用场景 - action_require = ["你想要闲聊或者随便附和", "有人提到你", "如果你刚刚进行了回复,不要对同一个话题重复回应"] - - # 关联类型 - associated_types = ["text"] - - def _parse_reply_target(self, target_message: str) -> tuple: - sender = "" - target = "" - if ":" in target_message or ":" in target_message: - # 使用正则表达式匹配中文或英文冒号 - parts = re.split(pattern=r"[::]", string=target_message, maxsplit=1) - if len(parts) == 2: - sender = parts[0].strip() - target = parts[1].strip() - return sender, target - - async def execute(self) -> Tuple[bool, str]: - """执行回复动作""" - logger.info(f"{self.log_prefix} 决定进行回复") - start_time = self.action_data.get("loop_start_time", time.time()) - - user_id = self.user_id - platform = self.platform - # logger.info(f"{self.log_prefix} 用户ID: {user_id}, 平台: {platform}") - person_id = get_person_info_manager().get_person_id(platform, user_id) - # logger.info(f"{self.log_prefix} 人物ID: {person_id}") - person_name = get_person_info_manager().get_value_sync(person_id, "person_name") - reply_to = f"{person_name}:{self.action_message.get('processed_plain_text', '')}" - logger.info(f"{self.log_prefix} 回复目标: {reply_to}") - - try: - if prepared_reply := self.action_data.get("prepared_reply", ""): - reply_text = prepared_reply - else: - try: - success, reply_set, _ = await asyncio.wait_for( - generator_api.generate_reply( - extra_info="", - reply_to=reply_to, - chat_id=self.chat_id, - request_type="chat.replyer.focus", - enable_tool=global_config.tool.enable_in_focus_chat, - ), - timeout=global_config.chat.thinking_timeout, - ) - except asyncio.TimeoutError: - logger.warning(f"{self.log_prefix} 回复生成超时 ({global_config.chat.thinking_timeout}s)") - return False, "timeout" - - # 检查从start_time以来的新消息数量 - # 获取动作触发时间或使用默认值 - current_time = time.time() - new_message_count = message_api.count_new_messages( - chat_id=self.chat_id, start_time=start_time, end_time=current_time - ) - - # 根据新消息数量决定是否使用reply_to - need_reply = new_message_count >= random.randint(2, 4) - logger.info( - f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,{'使用' if need_reply else '不使用'}引用回复" - ) - # 构建回复文本 - reply_text = "" - first_replied = False - reply_to_platform_id = f"{platform}:{user_id}" - for reply_seg in reply_set: - data = reply_seg[1] - if not first_replied: - if need_reply: - await self.send_text( - content=data, reply_to=reply_to, reply_to_platform_id=reply_to_platform_id, typing=False - ) - else: - await self.send_text(content=data, reply_to_platform_id=reply_to_platform_id, typing=False) - first_replied = True - else: - await self.send_text(content=data, reply_to_platform_id=reply_to_platform_id, typing=True) - reply_text += data - - # 存储动作记录 - reply_text = f"你对{person_name}进行了回复:{reply_text}" - - - if ENABLE_THINKING: - await mai_thinking_manager.get_mai_think(self.chat_id).do_think_after_response(reply_text) - - - await self.store_action_info( - action_build_into_prompt=False, - action_prompt_display=reply_text, - action_done=True, - ) - - # 重置NoReplyAction的连续计数器 - NoReplyAction.reset_consecutive_count() - - return success, reply_text - - except Exception as e: - logger.error(f"{self.log_prefix} 回复动作执行失败: {e}") - traceback.print_exc() - return False, f"回复失败: {str(e)}" - - @register_plugin class CoreActionsPlugin(BasePlugin): """核心动作插件 diff --git a/src/plugins/built_in/core_actions/reply.py b/src/plugins/built_in/core_actions/reply.py new file mode 100644 index 000000000..0b917f7b1 --- /dev/null +++ b/src/plugins/built_in/core_actions/reply.py @@ -0,0 +1,141 @@ + +# 导入新插件系统 +from src.plugin_system import BaseAction, ActionActivationType, ChatMode +from src.config.config import global_config +import random +import time +from typing import Tuple +import asyncio +import re +import traceback +# 导入依赖的系统组件 +from src.common.logger import get_logger + +# 导入API模块 - 标准Python包方式 +from src.plugin_system.apis import generator_api, message_api +from src.plugins.built_in.core_actions.no_reply import NoReplyAction +from src.person_info.person_info import get_person_info_manager +from src.chat.mai_thinking.mai_think import mai_thinking_manager +from src.mais4u.constant_s4u import ENABLE_THINKING + +logger = get_logger("reply_action") + +class ReplyAction(BaseAction): + """回复动作 - 参与聊天回复""" + + # 激活设置 + focus_activation_type = ActionActivationType.NEVER + normal_activation_type = ActionActivationType.NEVER + mode_enable = ChatMode.FOCUS + parallel_action = False + + # 动作基本信息 + action_name = "reply" + action_description = "参与聊天回复,发送文本进行表达" + + # 动作参数定义 + action_parameters = {} + + # 动作使用场景 + action_require = ["你想要闲聊或者随便附和", "有人提到你", "如果你刚刚进行了回复,不要对同一个话题重复回应"] + + # 关联类型 + associated_types = ["text"] + + def _parse_reply_target(self, target_message: str) -> tuple: + sender = "" + target = "" + if ":" in target_message or ":" in target_message: + # 使用正则表达式匹配中文或英文冒号 + parts = re.split(pattern=r"[::]", string=target_message, maxsplit=1) + if len(parts) == 2: + sender = parts[0].strip() + target = parts[1].strip() + return sender, target + + async def execute(self) -> Tuple[bool, str]: + """执行回复动作""" + logger.info(f"{self.log_prefix} 决定进行回复") + start_time = self.action_data.get("loop_start_time", time.time()) + + user_id = self.user_id + platform = self.platform + # logger.info(f"{self.log_prefix} 用户ID: {user_id}, 平台: {platform}") + person_id = get_person_info_manager().get_person_id(platform, user_id) + # logger.info(f"{self.log_prefix} 人物ID: {person_id}") + person_name = get_person_info_manager().get_value_sync(person_id, "person_name") + reply_to = f"{person_name}:{self.action_message.get('processed_plain_text', '')}" + logger.info(f"{self.log_prefix} 回复目标: {reply_to}") + + try: + if prepared_reply := self.action_data.get("prepared_reply", ""): + reply_text = prepared_reply + else: + try: + success, reply_set, _ = await asyncio.wait_for( + generator_api.generate_reply( + extra_info="", + reply_to=reply_to, + chat_id=self.chat_id, + request_type="chat.replyer.focus", + enable_tool=global_config.tool.enable_in_focus_chat, + ), + timeout=global_config.chat.thinking_timeout, + ) + except asyncio.TimeoutError: + logger.warning(f"{self.log_prefix} 回复生成超时 ({global_config.chat.thinking_timeout}s)") + return False, "timeout" + + # 检查从start_time以来的新消息数量 + # 获取动作触发时间或使用默认值 + current_time = time.time() + new_message_count = message_api.count_new_messages( + chat_id=self.chat_id, start_time=start_time, end_time=current_time + ) + + # 根据新消息数量决定是否使用reply_to + need_reply = new_message_count >= random.randint(2, 4) + logger.info( + f"{self.log_prefix} 从思考到回复,共有{new_message_count}条新消息,{'使用' if need_reply else '不使用'}引用回复" + ) + # 构建回复文本 + reply_text = "" + first_replied = False + reply_to_platform_id = f"{platform}:{user_id}" + for reply_seg in reply_set: + data = reply_seg[1] + if not first_replied: + if need_reply: + await self.send_text( + content=data, reply_to=reply_to, reply_to_platform_id=reply_to_platform_id, typing=False + ) + else: + await self.send_text(content=data, reply_to_platform_id=reply_to_platform_id, typing=False) + first_replied = True + else: + await self.send_text(content=data, reply_to_platform_id=reply_to_platform_id, typing=True) + reply_text += data + + # 存储动作记录 + reply_text = f"你对{person_name}进行了回复:{reply_text}" + + + if ENABLE_THINKING: + await mai_thinking_manager.get_mai_think(self.chat_id).do_think_after_response(reply_text) + + + await self.store_action_info( + action_build_into_prompt=False, + action_prompt_display=reply_text, + action_done=True, + ) + + # 重置NoReplyAction的连续计数器 + NoReplyAction.reset_consecutive_count() + + return success, reply_text + + except Exception as e: + logger.error(f"{self.log_prefix} 回复动作执行失败: {e}") + traceback.print_exc() + return False, f"回复失败: {str(e)}" \ No newline at end of file