feat:将no_reply内置
This commit is contained in:
@@ -25,7 +25,7 @@ from src.plugin_system.apis import generator_api, send_api, message_api, databas
|
|||||||
from src.chat.willing.willing_manager import get_willing_manager
|
from src.chat.willing.willing_manager import get_willing_manager
|
||||||
from src.mais4u.mai_think import mai_thinking_manager
|
from src.mais4u.mai_think import mai_thinking_manager
|
||||||
from src.mais4u.constant_s4u import ENABLE_S4U
|
from src.mais4u.constant_s4u import ENABLE_S4U
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
# no_reply逻辑已集成到heartFC_chat.py中,不再需要导入
|
||||||
from src.chat.chat_loop.hfc_utils import send_typing, stop_typing
|
from src.chat.chat_loop.hfc_utils import send_typing, stop_typing
|
||||||
|
|
||||||
ERROR_LOOP_INFO = {
|
ERROR_LOOP_INFO = {
|
||||||
@@ -427,7 +427,6 @@ class HeartFChatting:
|
|||||||
message_data = {}
|
message_data = {}
|
||||||
action_type = "no_action"
|
action_type = "no_action"
|
||||||
reply_text = "" # 初始化reply_text变量,避免UnboundLocalError
|
reply_text = "" # 初始化reply_text变量,避免UnboundLocalError
|
||||||
gen_task = None # 初始化gen_task变量,避免UnboundLocalError
|
|
||||||
reply_to_str = "" # 初始化reply_to_str变量
|
reply_to_str = "" # 初始化reply_to_str变量
|
||||||
|
|
||||||
# 创建新的循环信息
|
# 创建新的循环信息
|
||||||
@@ -484,18 +483,6 @@ class HeartFChatting:
|
|||||||
}
|
}
|
||||||
target_message = message_data
|
target_message = message_data
|
||||||
|
|
||||||
# 如果normal模式且不跳过规划器,开始一个回复生成进程,先准备好回复(其实是和planer同时进行的)
|
|
||||||
if not skip_planner:
|
|
||||||
reply_to_str = await self.build_reply_to_str(message_data)
|
|
||||||
gen_task = asyncio.create_task(
|
|
||||||
self._generate_response(
|
|
||||||
message_data=message_data,
|
|
||||||
available_actions=available_actions,
|
|
||||||
reply_to=reply_to_str,
|
|
||||||
request_type="chat.replyer.normal",
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if not skip_planner:
|
if not skip_planner:
|
||||||
planner_info = self.action_planner.get_necessary_info()
|
planner_info = self.action_planner.get_necessary_info()
|
||||||
prompt_info = await self.action_planner.build_planner_prompt(
|
prompt_info = await self.action_planner.build_planner_prompt(
|
||||||
@@ -520,193 +507,198 @@ class HeartFChatting:
|
|||||||
|
|
||||||
action_data["loop_start_time"] = loop_start_time
|
action_data["loop_start_time"] = loop_start_time
|
||||||
|
|
||||||
if action_type == "reply":
|
|
||||||
logger.info(f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复")
|
|
||||||
elif is_parallel:
|
|
||||||
logger.info(f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复, 同时执行{action_type}动作")
|
|
||||||
else:
|
|
||||||
# 只有在gen_task存在时才进行相关操作
|
|
||||||
if gen_task:
|
|
||||||
if not gen_task.done():
|
|
||||||
gen_task.cancel()
|
|
||||||
logger.debug(f"{self.log_prefix} 已取消预生成的回复任务")
|
|
||||||
logger.info(
|
|
||||||
f"{self.log_prefix}{global_config.bot.nickname} 原本想要回复,但选择执行{action_type},不发表回复"
|
|
||||||
)
|
|
||||||
elif generation_result := gen_task.result():
|
|
||||||
content = " ".join([item[1] for item in generation_result if item[0] == "text"])
|
|
||||||
logger.debug(f"{self.log_prefix} 预生成的回复任务已完成")
|
|
||||||
logger.info(
|
|
||||||
f"{self.log_prefix}{global_config.bot.nickname} 原本想要回复:{content},但选择执行{action_type},不发表回复"
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
logger.warning(f"{self.log_prefix} 预生成的回复任务未生成有效内容")
|
|
||||||
|
|
||||||
action_message = message_data or target_message
|
action_message = message_data or target_message
|
||||||
if action_type == "reply":
|
|
||||||
# 等待回复生成完毕
|
# 重构后的动作处理逻辑:先汇总所有动作,然后并行执行
|
||||||
if self.loop_mode == ChatMode.NORMAL:
|
actions = []
|
||||||
# 只有在gen_task存在时才等待
|
|
||||||
if not gen_task:
|
# 1. 添加Planner取得的动作
|
||||||
reply_to_str = await self.build_reply_to_str(message_data)
|
actions.append({
|
||||||
gen_task = asyncio.create_task(
|
"action_type": action_type,
|
||||||
self._generate_response(
|
"reasoning": reasoning,
|
||||||
message_data=message_data,
|
"action_data": action_data,
|
||||||
available_actions=available_actions,
|
"action_message": action_message,
|
||||||
reply_to=reply_to_str,
|
"available_actions": available_actions # 添加这个字段
|
||||||
request_type="chat.replyer.normal",
|
})
|
||||||
|
|
||||||
|
# 2. 如果不是reply动作且需要并行执行,额外添加reply动作
|
||||||
|
if action_type != "reply" and is_parallel:
|
||||||
|
actions.append({
|
||||||
|
"action_type": "reply",
|
||||||
|
"action_message": action_message,
|
||||||
|
"available_actions": available_actions
|
||||||
|
})
|
||||||
|
|
||||||
|
# 3. 并行执行所有动作
|
||||||
|
async def execute_action(action_info):
|
||||||
|
"""执行单个动作的通用函数"""
|
||||||
|
try:
|
||||||
|
if action_info["action_type"] == "no_reply":
|
||||||
|
# 直接处理no_reply逻辑,不再通过动作系统
|
||||||
|
reason = action_info.get("reasoning", "选择不回复")
|
||||||
|
logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}")
|
||||||
|
|
||||||
|
# 存储no_reply信息到数据库
|
||||||
|
await database_api.store_action_info(
|
||||||
|
chat_stream=self.chat_stream,
|
||||||
|
action_build_into_prompt=False,
|
||||||
|
action_prompt_display=reason,
|
||||||
|
action_done=True,
|
||||||
|
thinking_id=thinking_id,
|
||||||
|
action_data={"reason": reason},
|
||||||
|
action_name="no_reply",
|
||||||
|
)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"action_type": "no_reply",
|
||||||
|
"success": True,
|
||||||
|
"reply_text": "",
|
||||||
|
"command": ""
|
||||||
|
}
|
||||||
|
elif action_info["action_type"] != "reply":
|
||||||
|
# 执行普通动作
|
||||||
|
with Timer("动作执行", cycle_timers):
|
||||||
|
success, reply_text, command = await self._handle_action(
|
||||||
|
action_info["action_type"],
|
||||||
|
action_info["reasoning"],
|
||||||
|
action_info["action_data"],
|
||||||
|
cycle_timers,
|
||||||
|
thinking_id,
|
||||||
|
action_info["action_message"]
|
||||||
)
|
)
|
||||||
)
|
return {
|
||||||
|
"action_type": action_info["action_type"],
|
||||||
|
"success": success,
|
||||||
|
"reply_text": reply_text,
|
||||||
|
"command": command
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
# 执行回复动作
|
||||||
|
reply_to_str = await self.build_reply_to_str(action_info["action_message"])
|
||||||
|
request_type = "chat.replyer"
|
||||||
|
|
||||||
gather_timeout = global_config.chat.thinking_timeout
|
# 生成回复
|
||||||
try:
|
|
||||||
response_set = await asyncio.wait_for(gen_task, timeout=gather_timeout)
|
|
||||||
except asyncio.TimeoutError:
|
|
||||||
logger.warning(f"{self.log_prefix} 回复生成超时>{global_config.chat.thinking_timeout}s,已跳过")
|
|
||||||
response_set = None
|
|
||||||
|
|
||||||
# 模型炸了或超时,没有回复内容生成
|
|
||||||
if not response_set:
|
|
||||||
logger.warning(f"{self.log_prefix}模型未生成回复内容")
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
logger.info(f"{self.log_prefix}{global_config.bot.nickname} 决定进行回复 (focus模式)")
|
|
||||||
|
|
||||||
# 构建reply_to字符串
|
|
||||||
reply_to_str = await self.build_reply_to_str(action_message)
|
|
||||||
|
|
||||||
# 生成回复
|
|
||||||
with Timer("回复生成", cycle_timers):
|
|
||||||
response_set = await self._generate_response(
|
|
||||||
message_data=action_message,
|
|
||||||
available_actions=available_actions,
|
|
||||||
reply_to=reply_to_str,
|
|
||||||
request_type="chat.replyer.focus",
|
|
||||||
)
|
|
||||||
|
|
||||||
if not response_set:
|
|
||||||
logger.warning(f"{self.log_prefix}模型未生成回复内容")
|
|
||||||
return False
|
|
||||||
|
|
||||||
loop_info, reply_text, cycle_timers = await self._send_and_store_reply(
|
|
||||||
response_set, reply_to_str, loop_start_time, action_message, cycle_timers, thinking_id, plan_result
|
|
||||||
)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
else:
|
|
||||||
# 并行执行:同时进行回复发送和动作执行
|
|
||||||
# 先置空防止未定义错误
|
|
||||||
background_reply_task = None
|
|
||||||
background_action_task = None
|
|
||||||
# 如果是并行执行且在normal模式下,需要等待预生成的回复任务完成并发送回复
|
|
||||||
if self.loop_mode == ChatMode.NORMAL and is_parallel and gen_task:
|
|
||||||
|
|
||||||
async def handle_reply_task() -> Tuple[Optional[Dict[str, Any]], str, Dict[str, float]]:
|
|
||||||
# 等待预生成的回复任务完成
|
|
||||||
gather_timeout = global_config.chat.thinking_timeout
|
gather_timeout = global_config.chat.thinking_timeout
|
||||||
try:
|
try:
|
||||||
response_set = await asyncio.wait_for(gen_task, timeout=gather_timeout)
|
response_set = await asyncio.wait_for(
|
||||||
|
self._generate_response(
|
||||||
|
message_data=action_info["action_message"],
|
||||||
|
available_actions=action_info["available_actions"],
|
||||||
|
reply_to=reply_to_str,
|
||||||
|
request_type=request_type,
|
||||||
|
),
|
||||||
|
timeout=gather_timeout
|
||||||
|
)
|
||||||
except asyncio.TimeoutError:
|
except asyncio.TimeoutError:
|
||||||
logger.warning(
|
logger.warning(
|
||||||
f"{self.log_prefix} 并行执行:回复生成超时>{global_config.chat.thinking_timeout}s,已跳过"
|
f"{self.log_prefix} 并行执行:回复生成超时>{global_config.chat.thinking_timeout}s,已跳过"
|
||||||
)
|
)
|
||||||
return None, "", {}
|
return {
|
||||||
|
"action_type": "reply",
|
||||||
|
"success": False,
|
||||||
|
"reply_text": "",
|
||||||
|
"loop_info": None
|
||||||
|
}
|
||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
||||||
return None, "", {}
|
return {
|
||||||
|
"action_type": "reply",
|
||||||
|
"success": False,
|
||||||
|
"reply_text": "",
|
||||||
|
"loop_info": None
|
||||||
|
}
|
||||||
|
|
||||||
if not response_set:
|
if not response_set:
|
||||||
logger.warning(f"{self.log_prefix} 模型超时或生成回复内容为空")
|
logger.warning(f"{self.log_prefix} 模型超时或生成回复内容为空")
|
||||||
return None, "", {}
|
return {
|
||||||
|
"action_type": "reply",
|
||||||
|
"success": False,
|
||||||
|
"reply_text": "",
|
||||||
|
"loop_info": None
|
||||||
|
}
|
||||||
|
|
||||||
reply_to_str = await self.build_reply_to_str(action_message)
|
|
||||||
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(
|
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(
|
||||||
response_set,
|
response_set,
|
||||||
reply_to_str,
|
reply_to_str,
|
||||||
loop_start_time,
|
loop_start_time,
|
||||||
action_message,
|
action_info["action_message"],
|
||||||
cycle_timers,
|
cycle_timers,
|
||||||
thinking_id,
|
thinking_id,
|
||||||
plan_result,
|
plan_result,
|
||||||
)
|
)
|
||||||
return loop_info, reply_text, cycle_timers_reply
|
return {
|
||||||
|
"action_type": "reply",
|
||||||
# 执行回复任务并赋值到变量
|
"success": True,
|
||||||
background_reply_task = asyncio.create_task(handle_reply_task())
|
"reply_text": reply_text,
|
||||||
|
"loop_info": loop_info
|
||||||
# 动作执行任务
|
|
||||||
async def handle_action_task():
|
|
||||||
with Timer("动作执行", cycle_timers):
|
|
||||||
success, reply_text, command = await self._handle_action(
|
|
||||||
action_type, reasoning, action_data, cycle_timers, thinking_id, action_message
|
|
||||||
)
|
|
||||||
return success, reply_text, command
|
|
||||||
|
|
||||||
# 执行动作任务并赋值到变量
|
|
||||||
background_action_task = asyncio.create_task(handle_action_task())
|
|
||||||
|
|
||||||
reply_loop_info = None
|
|
||||||
reply_text_from_reply = ""
|
|
||||||
action_success = False
|
|
||||||
action_reply_text = ""
|
|
||||||
action_command = ""
|
|
||||||
|
|
||||||
# 并行执行所有任务
|
|
||||||
if background_reply_task:
|
|
||||||
results = await asyncio.gather(
|
|
||||||
background_reply_task, background_action_task, return_exceptions=True
|
|
||||||
)
|
|
||||||
# 处理回复任务结果
|
|
||||||
reply_result = results[0]
|
|
||||||
if isinstance(reply_result, BaseException):
|
|
||||||
logger.error(f"{self.log_prefix} 回复任务执行异常: {reply_result}")
|
|
||||||
elif reply_result and reply_result[0] is not None:
|
|
||||||
reply_loop_info, reply_text_from_reply, _ = reply_result
|
|
||||||
|
|
||||||
# 处理动作任务结果
|
|
||||||
action_task_result = results[1]
|
|
||||||
if isinstance(action_task_result, BaseException):
|
|
||||||
logger.error(f"{self.log_prefix} 动作任务执行异常: {action_task_result}")
|
|
||||||
else:
|
|
||||||
action_success, action_reply_text, action_command = action_task_result
|
|
||||||
else:
|
|
||||||
results = await asyncio.gather(background_action_task, return_exceptions=True)
|
|
||||||
# 只有动作任务
|
|
||||||
action_task_result = results[0]
|
|
||||||
if isinstance(action_task_result, BaseException):
|
|
||||||
logger.error(f"{self.log_prefix} 动作任务执行异常: {action_task_result}")
|
|
||||||
else:
|
|
||||||
action_success, action_reply_text, action_command = action_task_result
|
|
||||||
|
|
||||||
# 构建最终的循环信息
|
|
||||||
if reply_loop_info:
|
|
||||||
# 如果有回复信息,使用回复的loop_info作为基础
|
|
||||||
loop_info = reply_loop_info
|
|
||||||
# 更新动作执行信息
|
|
||||||
loop_info["loop_action_info"].update(
|
|
||||||
{
|
|
||||||
"action_taken": action_success,
|
|
||||||
"command": action_command,
|
|
||||||
"taken_time": time.time(),
|
|
||||||
}
|
}
|
||||||
)
|
except Exception as e:
|
||||||
reply_text = reply_text_from_reply
|
logger.error(f"{self.log_prefix} 执行动作时出错: {e}")
|
||||||
else:
|
return {
|
||||||
# 没有回复信息,构建纯动作的loop_info
|
"action_type": action_info["action_type"],
|
||||||
loop_info = {
|
"success": False,
|
||||||
"loop_plan_info": {
|
"reply_text": "",
|
||||||
"action_result": plan_result.get("action_result", {}),
|
"loop_info": None,
|
||||||
},
|
"error": str(e)
|
||||||
"loop_action_info": {
|
|
||||||
"action_taken": action_success,
|
|
||||||
"reply_text": action_reply_text,
|
|
||||||
"command": action_command,
|
|
||||||
"taken_time": time.time(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
reply_text = action_reply_text
|
|
||||||
|
# 创建所有动作的后台任务
|
||||||
|
action_tasks = [asyncio.create_task(execute_action(action)) for action in actions]
|
||||||
|
|
||||||
|
# 并行执行所有任务
|
||||||
|
results = await asyncio.gather(*action_tasks, return_exceptions=True)
|
||||||
|
|
||||||
|
# 处理执行结果
|
||||||
|
reply_loop_info = None
|
||||||
|
reply_text_from_reply = ""
|
||||||
|
action_success = False
|
||||||
|
action_reply_text = ""
|
||||||
|
action_command = ""
|
||||||
|
|
||||||
|
for i, result in enumerate(results):
|
||||||
|
if isinstance(result, BaseException):
|
||||||
|
logger.error(f"{self.log_prefix} 动作执行异常: {result}")
|
||||||
|
continue
|
||||||
|
|
||||||
|
action_info = actions[i]
|
||||||
|
if result["action_type"] != "reply":
|
||||||
|
action_success = result["success"]
|
||||||
|
action_reply_text = result["reply_text"]
|
||||||
|
action_command = result.get("command", "")
|
||||||
|
elif result["action_type"] == "reply":
|
||||||
|
if result["success"]:
|
||||||
|
reply_loop_info = result["loop_info"]
|
||||||
|
reply_text_from_reply = result["reply_text"]
|
||||||
|
else:
|
||||||
|
logger.warning(f"{self.log_prefix} 回复动作执行失败")
|
||||||
|
|
||||||
|
# 构建最终的循环信息
|
||||||
|
if reply_loop_info:
|
||||||
|
# 如果有回复信息,使用回复的loop_info作为基础
|
||||||
|
loop_info = reply_loop_info
|
||||||
|
# 更新动作执行信息
|
||||||
|
loop_info["loop_action_info"].update(
|
||||||
|
{
|
||||||
|
"action_taken": action_success,
|
||||||
|
"command": action_command,
|
||||||
|
"taken_time": time.time(),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
reply_text = reply_text_from_reply
|
||||||
|
else:
|
||||||
|
# 没有回复信息,构建纯动作的loop_info
|
||||||
|
loop_info = {
|
||||||
|
"loop_plan_info": {
|
||||||
|
"action_result": plan_result.get("action_result", {}),
|
||||||
|
},
|
||||||
|
"loop_action_info": {
|
||||||
|
"action_taken": action_success,
|
||||||
|
"reply_text": action_reply_text,
|
||||||
|
"command": action_command,
|
||||||
|
"taken_time": time.time(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
reply_text = action_reply_text
|
||||||
|
|
||||||
self.last_action = action_type
|
self.last_action = action_type
|
||||||
|
|
||||||
@@ -722,7 +714,7 @@ class HeartFChatting:
|
|||||||
|
|
||||||
# 管理no_reply计数器:当执行了非no_reply动作时,重置计数器
|
# 管理no_reply计数器:当执行了非no_reply动作时,重置计数器
|
||||||
if action_type != "no_reply" and action_type != "no_action":
|
if action_type != "no_reply" and action_type != "no_action":
|
||||||
# 导入NoReplyAction并重置计数器
|
# no_reply逻辑已集成到heartFC_chat.py中,直接重置计数器
|
||||||
self.recent_interest_records.clear()
|
self.recent_interest_records.clear()
|
||||||
self.no_reply_consecutive = 0
|
self.no_reply_consecutive = 0
|
||||||
logger.info(f"{self.log_prefix} 执行了{action_type}动作,重置no_reply计数器")
|
logger.info(f"{self.log_prefix} 执行了{action_type}动作,重置no_reply计数器")
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ class ActionPlanner:
|
|||||||
by_what = "聊天内容"
|
by_what = "聊天内容"
|
||||||
target_prompt = '\n "target_message_id":"触发action的消息id"'
|
target_prompt = '\n "target_message_id":"触发action的消息id"'
|
||||||
no_action_block = f"""重要说明:
|
no_action_block = f"""重要说明:
|
||||||
- 'no_reply' 表示只进行不进行回复,等待合适的回复时机
|
- 'no_reply' 表示只进行不进行回复,等待合适的回复时机(由系统直接处理)
|
||||||
- 当你刚刚发送了消息,没有人回复时,选择no_reply
|
- 当你刚刚发送了消息,没有人回复时,选择no_reply
|
||||||
- 当你一次发送了太多消息,为了避免打扰聊天节奏,选择no_reply
|
- 当你一次发送了太多消息,为了避免打扰聊天节奏,选择no_reply
|
||||||
|
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
from typing import Tuple, List
|
|
||||||
from collections import deque
|
|
||||||
|
|
||||||
# 导入新插件系统
|
|
||||||
from src.plugin_system import BaseAction, ActionActivationType, ChatMode
|
|
||||||
|
|
||||||
# 导入依赖的系统组件
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
|
|
||||||
|
|
||||||
logger = get_logger("no_reply_action")
|
|
||||||
|
|
||||||
|
|
||||||
class NoReplyAction(BaseAction):
|
|
||||||
"""不回复动作,支持waiting和breaking两种形式.
|
|
||||||
|
|
||||||
waiting形式:
|
|
||||||
- 只要有新消息就结束动作
|
|
||||||
- 记录新消息的兴趣度到列表(最多保留最近三项)
|
|
||||||
- 如果最近三次动作都是no_reply,且最近新消息列表兴趣度之和小于阈值,就进入breaking形式
|
|
||||||
|
|
||||||
breaking形式:
|
|
||||||
- 和原有逻辑一致,需要消息满足一定数量或累计一定兴趣值才结束动作
|
|
||||||
"""
|
|
||||||
|
|
||||||
focus_activation_type = ActionActivationType.NEVER
|
|
||||||
normal_activation_type = ActionActivationType.NEVER
|
|
||||||
mode_enable = ChatMode.FOCUS
|
|
||||||
parallel_action = False
|
|
||||||
|
|
||||||
# 动作基本信息
|
|
||||||
action_name = "no_reply"
|
|
||||||
action_description = "暂时不回复消息"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 兴趣值退出阈值
|
|
||||||
_interest_exit_threshold = 3.0
|
|
||||||
# 消息数量退出阈值
|
|
||||||
_min_exit_message_count = 3
|
|
||||||
_max_exit_message_count = 6
|
|
||||||
|
|
||||||
# 动作参数定义
|
|
||||||
action_parameters = {}
|
|
||||||
|
|
||||||
# 动作使用场景
|
|
||||||
action_require = [""]
|
|
||||||
|
|
||||||
# 关联类型
|
|
||||||
associated_types = []
|
|
||||||
|
|
||||||
async def execute(self) -> Tuple[bool, str]:
|
|
||||||
"""执行不回复动作"""
|
|
||||||
|
|
||||||
try:
|
|
||||||
reason = self.action_data.get("reason", "")
|
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}")
|
|
||||||
|
|
||||||
await self.store_action_info(
|
|
||||||
action_build_into_prompt=False,
|
|
||||||
action_prompt_display=reason,
|
|
||||||
action_done=True,
|
|
||||||
)
|
|
||||||
return True, reason
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"{self.log_prefix} 不回复动作执行失败: {e}")
|
|
||||||
exit_reason = f"执行异常: {str(e)}"
|
|
||||||
full_prompt = f"no_reply执行异常: {exit_reason},你思考是否要进行回复"
|
|
||||||
await self.store_action_info(
|
|
||||||
action_build_into_prompt=True,
|
|
||||||
action_prompt_display=full_prompt,
|
|
||||||
action_done=True,
|
|
||||||
)
|
|
||||||
return False, f"不回复动作执行失败: {e}"
|
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 1,
|
"manifest_version": 1,
|
||||||
"name": "核心动作插件 (Core Actions)",
|
"name": "Emoji插件 (Emoji Actions)",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "系统核心动作插件,提供基础聊天交互功能,包括回复、不回复、表情包发送和聊天模式切换等核心功能。",
|
"description": "可以发送和管理Emoji",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "MaiBot团队",
|
"name": "SengokuCola",
|
||||||
"url": "https://github.com/MaiM-with-u"
|
"url": "https://github.com/MaiM-with-u"
|
||||||
},
|
},
|
||||||
"license": "GPL-v3.0-or-later",
|
"license": "GPL-v3.0-or-later",
|
||||||
|
|
||||||
"host_application": {
|
"host_application": {
|
||||||
"min_version": "0.8.0"
|
"min_version": "0.10.0"
|
||||||
},
|
},
|
||||||
"homepage_url": "https://github.com/MaiM-with-u/maibot",
|
"homepage_url": "https://github.com/MaiM-with-u/maibot",
|
||||||
"repository_url": "https://github.com/MaiM-with-u/maibot",
|
"repository_url": "https://github.com/MaiM-with-u/maibot",
|
||||||
"keywords": ["core", "chat", "reply", "emoji", "action", "built-in"],
|
"keywords": ["emoji", "action", "built-in"],
|
||||||
"categories": ["Core System", "Chat Management"],
|
"categories": ["Emoji"],
|
||||||
|
|
||||||
"default_locale": "zh-CN",
|
"default_locale": "zh-CN",
|
||||||
"locales_path": "_locales",
|
"locales_path": "_locales",
|
||||||
@@ -24,11 +24,6 @@
|
|||||||
"is_built_in": true,
|
"is_built_in": true,
|
||||||
"plugin_type": "action_provider",
|
"plugin_type": "action_provider",
|
||||||
"components": [
|
"components": [
|
||||||
{
|
|
||||||
"type": "action",
|
|
||||||
"name": "no_reply",
|
|
||||||
"description": "暂时不回复消息,等待新消息或超时"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"type": "action",
|
"type": "action",
|
||||||
"name": "emoji",
|
"name": "emoji",
|
||||||
@@ -9,8 +9,7 @@ from src.common.logger import get_logger
|
|||||||
|
|
||||||
# 导入API模块 - 标准Python包方式
|
# 导入API模块 - 标准Python包方式
|
||||||
from src.plugin_system.apis import emoji_api, llm_api, message_api
|
from src.plugin_system.apis import emoji_api, llm_api, message_api
|
||||||
# 注释:不再需要导入NoReplyAction,因为计数器管理已移至heartFC_chat.py
|
# NoReplyAction已集成到heartFC_chat.py中,不再需要导入
|
||||||
# from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
|
|
||||||
|
|
||||||
@@ -149,8 +148,7 @@ class EmojiAction(BaseAction):
|
|||||||
logger.error(f"{self.log_prefix} 表情包发送失败")
|
logger.error(f"{self.log_prefix} 表情包发送失败")
|
||||||
return False, "表情包发送失败"
|
return False, "表情包发送失败"
|
||||||
|
|
||||||
# 注释:重置NoReplyAction的连续计数器现在由heartFC_chat.py统一管理
|
# no_reply计数器现在由heartFC_chat.py统一管理,无需在此重置
|
||||||
# NoReplyAction.reset_consecutive_count()
|
|
||||||
|
|
||||||
return True, f"发送表情包: {emoji_description}"
|
return True, f"发送表情包: {emoji_description}"
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ from src.plugin_system.base.config_types import ConfigField
|
|||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
|
|
||||||
# 导入API模块 - 标准Python包方式
|
# 导入API模块 - 标准Python包方式
|
||||||
from src.plugins.built_in.core_actions.no_reply import NoReplyAction
|
# NoReplyAction已集成到heartFC_chat.py中,不再需要导入
|
||||||
from src.plugins.built_in.core_actions.emoji import EmojiAction
|
from src.plugins.built_in.core_actions.emoji import EmojiAction
|
||||||
|
|
||||||
logger = get_logger("core_actions")
|
logger = get_logger("core_actions")
|
||||||
@@ -50,10 +50,9 @@ class CoreActionsPlugin(BasePlugin):
|
|||||||
config_schema: dict = {
|
config_schema: dict = {
|
||||||
"plugin": {
|
"plugin": {
|
||||||
"enabled": ConfigField(type=bool, default=True, description="是否启用插件"),
|
"enabled": ConfigField(type=bool, default=True, description="是否启用插件"),
|
||||||
"config_version": ConfigField(type=str, default="0.5.0", description="配置文件版本"),
|
"config_version": ConfigField(type=str, default="0.6.0", description="配置文件版本"),
|
||||||
},
|
},
|
||||||
"components": {
|
"components": {
|
||||||
"enable_no_reply": ConfigField(type=bool, default=True, description="是否启用不回复动作"),
|
|
||||||
"enable_emoji": ConfigField(type=bool, default=True, description="是否启用发送表情/图片动作"),
|
"enable_emoji": ConfigField(type=bool, default=True, description="是否启用发送表情/图片动作"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -63,8 +62,6 @@ class CoreActionsPlugin(BasePlugin):
|
|||||||
|
|
||||||
# --- 根据配置注册组件 ---
|
# --- 根据配置注册组件 ---
|
||||||
components = []
|
components = []
|
||||||
if self.get_config("components.enable_no_reply", True):
|
|
||||||
components.append((NoReplyAction.get_action_info(), NoReplyAction))
|
|
||||||
if self.get_config("components.enable_emoji", True):
|
if self.get_config("components.enable_emoji", True):
|
||||||
components.append((EmojiAction.get_action_info(), EmojiAction))
|
components.append((EmojiAction.get_action_info(), EmojiAction))
|
||||||
|
|
||||||
Reference in New Issue
Block a user