ref:修改了plan的执行记录展示模式,现在每个动作的执行都会被记录

This commit is contained in:
SengokuCola
2025-10-02 20:11:44 +08:00
parent 6a0a07582e
commit dbdf650b1d
19 changed files with 521 additions and 207 deletions

View File

@@ -282,7 +282,7 @@ class BrainChatting:
prompt_info = (modified_message.llm_prompt, prompt_info[1])
with Timer("规划器", cycle_timers):
action_to_use_info, _ = await self.action_planner.plan(
action_to_use_info = await self.action_planner.plan(
loop_start_time=self.last_read_time,
available_actions=available_actions,
)
@@ -413,8 +413,8 @@ class BrainChatting:
logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}")
return False, "", ""
# 处理动作并获取结果
result = await action_handler.execute()
# 处理动作并获取结果(固定记录一次动作信息)
result = await action_handler.run()
success, action_text = result
command = ""
@@ -481,11 +481,11 @@ class BrainChatting:
try:
with Timer(f"动作{action_planner_info.action_type}", cycle_timers):
if action_planner_info.action_type == "no_reply":
# 直接处理no_action逻辑,不再通过动作系统
# 直接处理no_reply逻辑,不再通过动作系统
reason = action_planner_info.reasoning or "选择不回复"
# logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}")
# 存储no_action信息到数据库
# 存储no_reply信息到数据库
await database_api.store_action_info(
chat_stream=self.chat_stream,
action_build_into_prompt=False,
@@ -493,9 +493,9 @@ class BrainChatting:
action_done=True,
thinking_id=thinking_id,
action_data={"reason": reason},
action_name="no_action",
action_name="no_reply",
)
return {"action_type": "no_action", "success": True, "reply_text": "", "command": ""}
return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""}
elif action_planner_info.action_type == "reply":
try:

View File

@@ -152,10 +152,10 @@ class BrainPlanner:
action_planner_infos = []
try:
action = action_json.get("action", "no_action")
action = action_json.get("action", "no_reply")
reasoning = action_json.get("reason", "未提供原因")
action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]}
# 非no_action动作需要target_message_id
# 非no_reply动作需要target_message_id
target_message = None
if target_message_id := action_json.get("target_message_id"):
@@ -215,12 +215,11 @@ class BrainPlanner:
self,
available_actions: Dict[str, ActionInfo],
loop_start_time: float = 0.0,
) -> Tuple[List[ActionPlannerInfo], Optional["DatabaseMessages"]]:
) -> List[ActionPlannerInfo]:
# sourcery skip: use-named-expression
"""
规划器 (Planner): 使用LLM根据上下文决定做出什么动作。
"""
target_message: Optional["DatabaseMessages"] = None
# 获取聊天上下文
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
@@ -274,12 +273,7 @@ class BrainPlanner:
loop_start_time=loop_start_time,
)
# 获取target_message如果有非no_action的动作)
non_no_actions = [a for a in actions if a.action_type != "no_reply"]
if non_no_actions:
target_message = non_no_actions[0].action_message
return actions, target_message
return actions
async def build_planner_prompt(
self,
@@ -489,7 +483,7 @@ class BrainPlanner:
else:
actions = self._create_no_reply("规划器没有获得LLM响应", available_actions)
# 添加循环开始时间到所有非no_action动作
# 添加循环开始时间到所有非no_reply动作
for action in actions:
action.action_data = action.action_data or {}
action.action_data["loop_start_time"] = loop_start_time
@@ -501,7 +495,7 @@ class BrainPlanner:
return actions
def _create_no_reply(self, reasoning: str, available_actions: Dict[str, ActionInfo]) -> List[ActionPlannerInfo]:
"""创建no_action"""
"""创建no_reply"""
return [
ActionPlannerInfo(
action_type="no_reply",

View File

@@ -98,6 +98,8 @@ class HeartFChatting:
self.last_read_time = time.time() - 2
self.no_reply_until_call = False
self.is_mute = False
async def start(self):
@@ -175,6 +177,8 @@ class HeartFChatting:
)
if len(recent_messages_list) >= 1:
# for message in recent_messages_list:
# print(message.processed_plain_text)
# !处理no_reply_until_call逻辑
if self.no_reply_until_call:
for message in recent_messages_list:
@@ -185,6 +189,7 @@ class HeartFChatting:
or time.time() - self.last_read_time > 600
):
self.no_reply_until_call = False
self.last_read_time = time.time()
break
# 没有提到,继续保持沉默
if self.no_reply_until_call:
@@ -333,7 +338,7 @@ class HeartFChatting:
prompt_info = (modified_message.llm_prompt, prompt_info[1])
with Timer("规划器", cycle_timers):
action_to_use_info, _ = await self.action_planner.plan(
action_to_use_info = await self.action_planner.plan(
loop_start_time=self.last_read_time,
available_actions=available_actions,
)
@@ -450,7 +455,7 @@ class HeartFChatting:
async def _handle_action(
self,
action: str,
reasoning: str,
action_reasoning: str,
action_data: dict,
cycle_timers: Dict[str, float],
thinking_id: str,
@@ -461,11 +466,11 @@ class HeartFChatting:
参数:
action: 动作类型
reasoning: 决策理由
action_reasoning: 决策理由
action_data: 动作数据,包含不同动作需要的参数
cycle_timers: 计时器字典
thinking_id: 思考ID
action_message: 消息数据
返回:
tuple[bool, str, str]: (是否执行了动作, 思考消息ID, 命令)
"""
@@ -475,11 +480,11 @@ class HeartFChatting:
action_handler = self.action_manager.create_action(
action_name=action,
action_data=action_data,
reasoning=reasoning,
cycle_timers=cycle_timers,
thinking_id=thinking_id,
chat_stream=self.chat_stream,
log_prefix=self.log_prefix,
action_reasoning=action_reasoning,
action_message=action_message,
)
except Exception as e:
@@ -491,7 +496,7 @@ class HeartFChatting:
logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}")
return False, "", ""
# 处理动作并获取结果
# 处理动作并获取结果(固定记录一次动作信息)
result = await action_handler.execute()
success, action_text = result
command = ""
@@ -558,42 +563,67 @@ class HeartFChatting:
"""执行单个动作的通用函数"""
try:
with Timer(f"动作{action_planner_info.action_type}", cycle_timers):
# 直接当场执行no_reply逻辑
if action_planner_info.action_type == "no_reply":
# 直接处理no_action逻辑,不再通过动作系统
# 直接处理no_reply逻辑,不再通过动作系统
reason = action_planner_info.reasoning or "选择不回复"
# logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}")
# 存储no_action信息到数据库
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_action",
action_data={},
action_name="no_reply",
action_reasoning=reason,
)
return {"action_type": "no_action", "success": True, "reply_text": "", "command": ""}
elif action_planner_info.action_type == "wait_time":
action_planner_info.action_data = action_planner_info.action_data or {}
logger.info(f"{self.log_prefix} 等待{action_planner_info.action_data['time']}秒后回复")
await asyncio.sleep(action_planner_info.action_data["time"])
return {"action_type": "wait_time", "success": True, "reply_text": "", "command": ""}
return {"action_type": "no_reply", "success": True, "reply_text": "", "command": ""}
elif action_planner_info.action_type == "no_reply_until_call":
# 直接当场执行no_reply_until_call逻辑
logger.info(f"{self.log_prefix} 保持沉默,直到有人直接叫的名字")
reason = action_planner_info.reasoning or "选择不回复"
self.no_reply_until_call = True
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={},
action_name="no_reply_until_call",
action_reasoning=reason,
)
return {"action_type": "no_reply_until_call", "success": True, "reply_text": "", "command": ""}
elif action_planner_info.action_type == "reply":
# 直接当场执行reply逻辑
try:
reason = action_planner_info.reasoning or "选择回复"
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={},
action_name="reply",
action_reasoning=reason,
)
success, llm_response = await generator_api.generate_reply(
chat_stream=self.chat_stream,
reply_message=action_planner_info.action_message,
available_actions=available_actions,
chosen_actions=chosen_action_plan_infos,
reply_reason=action_planner_info.reasoning or "",
reply_reason=reason,
enable_tool=global_config.tool.enable_tool,
request_type="replyer",
from_plugin=False,
@@ -627,18 +657,16 @@ class HeartFChatting:
"reply_text": reply_text,
"loop_info": loop_info,
}
# 其他动作
else:
# 执行普通动作
with Timer("动作执行", cycle_timers):
success, reply_text, command = await self._handle_action(
action_planner_info.action_type,
action_planner_info.reasoning or "",
action_planner_info.action_data or {},
cycle_timers,
thinking_id,
action_planner_info.action_message,
action = action_planner_info.action_type,
action_reasoning = action_planner_info.action_reasoning or "",
action_data = action_planner_info.action_data or {},
cycle_timers = cycle_timers,
thinking_id = thinking_id,
action_message= action_planner_info.action_message,
)
return {
"action_type": action_planner_info.action_type,

View File

@@ -32,7 +32,7 @@ class ActionManager:
self,
action_name: str,
action_data: dict,
reasoning: str,
action_reasoning: str,
cycle_timers: dict,
thinking_id: str,
chat_stream: ChatStream,
@@ -46,7 +46,7 @@ class ActionManager:
Args:
action_name: 动作名称
action_data: 动作数据
reasoning: 执行理由
action_reasoning: 执行理由
cycle_timers: 计时器字典
thinking_id: 思考ID
chat_stream: 聊天流
@@ -77,7 +77,7 @@ class ActionManager:
# 创建动作实例
instance = component_class(
action_data=action_data,
reasoning=reasoning,
action_reasoning=action_reasoning,
cycle_timers=cycle_timers,
thinking_id=thinking_id,
chat_stream=chat_stream,

View File

@@ -44,10 +44,7 @@ def init_prompt():
**聊天内容**
{chat_content_block}
**动作记录**
{actions_before_now_block}
**可用的action**
**可选的action**
reply
动作描述:
1.你可以选择呼叫了你的名字,但是你没有做出回应的消息进行回复
@@ -76,7 +73,10 @@ no_reply_until_call
{action_options_text}
请选择合适的action并说明触发action的消息id和选择该action的原因。消息id格式:m+数字
**你之前的action执行和思考记录**
{actions_before_now_block}
请选择**可选的**且符合使用条件的action并说明触发action的消息id(消息id格式:m+数字)
先输出你的选择思考理由再输出你选择的action理由是一段平文本不要分点精简。
**动作选择要求**
请你根据聊天内容,用户的最新消息和以下标准选择合适的动作:
@@ -99,9 +99,7 @@ no_reply_until_call
"target_message_id":"触发动作的消息id",
//对应参数
}}
```
""",
```""",
"planner_prompt",
)
@@ -133,6 +131,9 @@ class ActionPlanner:
self.last_obs_time_mark = 0.0
self.plan_log:List[Tuple[str,str,ActionPlannerInfo]] = []
def find_message_by_id(
self, message_id: str, message_id_list: List[Tuple[str, "DatabaseMessages"]]
) -> Optional["DatabaseMessages"]:
@@ -157,15 +158,16 @@ class ActionPlanner:
action_json: dict,
message_id_list: List[Tuple[str, "DatabaseMessages"]],
current_available_actions: List[Tuple[str, ActionInfo]],
extracted_reasoning: str = "",
) -> List[ActionPlannerInfo]:
"""解析单个action JSON并返回ActionPlannerInfo列表"""
action_planner_infos = []
try:
action = action_json.get("action", "no_action")
action = action_json.get("action", "no_reply")
reasoning = action_json.get("reason", "未提供原因")
action_data = {key: value for key, value in action_json.items() if key not in ["action", "reason"]}
# 非no_action动作需要target_message_id
# 非no_reply动作需要target_message_id
target_message = None
if target_message_id := action_json.get("target_message_id"):
@@ -202,6 +204,7 @@ class ActionPlanner:
action_data=action_data,
action_message=target_message,
available_actions=available_actions_dict,
action_reasoning=extracted_reasoning if extracted_reasoning else None,
)
)
@@ -216,6 +219,7 @@ class ActionPlanner:
action_data={},
action_message=None,
available_actions=available_actions_dict,
action_reasoning=extracted_reasoning if extracted_reasoning else None,
)
)
@@ -225,12 +229,11 @@ class ActionPlanner:
self,
available_actions: Dict[str, ActionInfo],
loop_start_time: float = 0.0,
) -> Tuple[List[ActionPlannerInfo], Optional["DatabaseMessages"]]:
) -> List[ActionPlannerInfo]:
# sourcery skip: use-named-expression
"""
规划器 (Planner): 使用LLM根据上下文决定做出什么动作。
"""
target_message: Optional["DatabaseMessages"] = None
# 获取聊天上下文
message_list_before_now = get_raw_msg_before_timestamp_with_chat(
@@ -276,7 +279,7 @@ class ActionPlanner:
)
# 调用LLM获取决策
actions = await self._execute_main_planner(
reasoning, actions = await self._execute_main_planner(
prompt=prompt,
message_id_list=message_id_list,
filtered_actions=filtered_actions,
@@ -284,12 +287,22 @@ class ActionPlanner:
loop_start_time=loop_start_time,
)
# 获取target_message如果有非no_action的动作)
non_no_actions = [a for a in actions if a.action_type != "no_reply"]
if non_no_actions:
target_message = non_no_actions[0].action_message
self.add_plan_log(reasoning, actions)
return actions
def add_plan_log(self, reasoning: str, actions: List[ActionPlannerInfo]):
self.plan_log.append((reasoning, time.time(), actions))
if len(self.plan_log) > 100:
self.plan_log.pop(0)
def get_plan_log_str(self) -> str:
plan_log_str = ""
for reasoning, time, actions in self.plan_log:
time = datetime.fromtimestamp(time).strftime("%H:%M:%S")
plan_log_str += f"{time}:{reasoning}|使用了{','.join([action.action_type for action in actions])}\n"
return plan_log_str
return actions, target_message
async def build_planner_prompt(
self,
@@ -302,18 +315,8 @@ class ActionPlanner:
) -> tuple[str, List[Tuple[str, "DatabaseMessages"]]]:
"""构建 Planner LLM 的提示词 (获取模板并填充数据)"""
try:
# 获取最近执行过的动作
actions_before_now = get_actions_by_timestamp_with_chat(
chat_id=self.chat_id,
timestamp_start=time.time() - 600,
timestamp_end=time.time(),
limit=6,
)
actions_before_now_block = build_readable_actions(actions=actions_before_now)
if actions_before_now_block:
actions_before_now_block = f"你刚刚选择并执行过的action是\n{actions_before_now_block}"
else:
actions_before_now_block = ""
actions_before_now_block=self.get_plan_log_str()
# 构建聊天上下文描述
chat_context_description = "你现在正在一个群聊中"
@@ -447,7 +450,7 @@ class ActionPlanner:
filtered_actions: Dict[str, ActionInfo],
available_actions: Dict[str, ActionInfo],
loop_start_time: float,
) -> List[ActionPlannerInfo]:
) -> Tuple[str,List[ActionPlannerInfo]]:
"""执行主规划器"""
llm_content = None
actions: List[ActionPlannerInfo] = []
@@ -456,8 +459,8 @@ class ActionPlanner:
# 调用LLM
llm_content, (reasoning_content, _, _) = await self.planner_llm.generate_response_async(prompt=prompt)
# logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}")
# logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}")
logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}")
logger.info(f"{self.log_prefix}规划器原始响应: {llm_content}")
if global_config.debug.show_prompt:
logger.info(f"{self.log_prefix}规划器原始提示词: {prompt}")
@@ -472,7 +475,7 @@ class ActionPlanner:
except Exception as req_e:
logger.error(f"{self.log_prefix}LLM 请求执行失败: {req_e}")
return [
return f"LLM 请求失败,模型出现问题: {req_e}",[
ActionPlannerInfo(
action_type="no_reply",
reasoning=f"LLM 请求失败,模型出现问题: {req_e}",
@@ -485,11 +488,12 @@ class ActionPlanner:
# 解析LLM响应
if llm_content:
try:
if json_objects := self._extract_json_from_markdown(llm_content):
json_objects, extracted_reasoning = self._extract_json_from_markdown(llm_content)
if json_objects:
logger.debug(f"{self.log_prefix}从响应中提取到{len(json_objects)}个JSON对象")
filtered_actions_list = list(filtered_actions.items())
for json_obj in json_objects:
actions.extend(self._parse_single_action(json_obj, message_id_list, filtered_actions_list))
actions.extend(self._parse_single_action(json_obj, message_id_list, filtered_actions_list, extracted_reasoning))
else:
# 尝试解析为直接的JSON
logger.warning(f"{self.log_prefix}LLM没有返回可用动作: {llm_content}")
@@ -502,17 +506,17 @@ class ActionPlanner:
else:
actions = self._create_no_reply("规划器没有获得LLM响应", available_actions)
# 添加循环开始时间到所有非no_action动作
# 添加循环开始时间到所有非no_reply动作
for action in actions:
action.action_data = action.action_data or {}
action.action_data["loop_start_time"] = loop_start_time
logger.debug(f"{self.log_prefix}规划器选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}")
return actions
return extracted_reasoning,actions
def _create_no_reply(self, reasoning: str, available_actions: Dict[str, ActionInfo]) -> List[ActionPlannerInfo]:
"""创建no_action"""
"""创建no_reply"""
return [
ActionPlannerInfo(
action_type="no_reply",
@@ -523,15 +527,26 @@ class ActionPlanner:
)
]
def _extract_json_from_markdown(self, content: str) -> List[dict]:
def _extract_json_from_markdown(self, content: str) -> Tuple[List[dict], str]:
# sourcery skip: for-append-to-extend
"""从Markdown格式的内容中提取JSON对象"""
"""从Markdown格式的内容中提取JSON对象和推理内容"""
json_objects = []
reasoning_content = ""
# 使用正则表达式查找```json包裹的JSON内容
json_pattern = r"```json\s*(.*?)\s*```"
matches = re.findall(json_pattern, content, re.DOTALL)
# 提取JSON之前的内容作为推理文本
if matches:
# 找到第一个```json的位置
first_json_pos = content.find("```json")
if first_json_pos > 0:
reasoning_content = content[:first_json_pos].strip()
# 清理推理内容中的注释标记
reasoning_content = re.sub(r"^//\s*", "", reasoning_content, flags=re.MULTILINE)
reasoning_content = reasoning_content.strip()
for match in matches:
try:
# 清理可能的注释和格式问题
@@ -549,7 +564,7 @@ class ActionPlanner:
logger.warning(f"解析JSON块失败: {e}, 块内容: {match[:100]}...")
continue
return json_objects
return json_objects, reasoning_content
init_prompt()

View File

@@ -216,6 +216,7 @@ def get_actions_by_timestamp_with_chat(
chat_id=action.chat_id,
chat_info_stream_id=action.chat_info_stream_id,
chat_info_platform=action.chat_info_platform,
action_reasoning=action.action_reasoning,
)
for action in actions
]
@@ -559,14 +560,12 @@ def build_readable_actions(actions: List[DatabaseActionRecords], mode: str = "re
output_lines = []
current_time = time.time()
# The get functions return actions sorted ascending by time. Let's reverse it to show newest first.
# sorted_actions = sorted(actions, key=lambda x: x.get("time", 0), reverse=True)
for action in actions:
action_time = action.time or current_time
action_name = action.action_name or "未知动作"
# action_reason = action.get(action_data")
if action_name in ["no_action", "no_action"]:
if action_name in ["no_reply", "no_reply"]:
continue
action_prompt_display = action.action_prompt_display or "无具体内容"
@@ -588,6 +587,7 @@ def build_readable_actions(actions: List[DatabaseActionRecords], mode: str = "re
line = f"{time_ago_str},你使用了“{action_name}”,具体内容是:“{action_prompt_display}"
output_lines.append(line)
return "\n".join(output_lines)

View File

@@ -220,6 +220,7 @@ class DatabaseActionRecords(BaseDataModel):
chat_id: str,
chat_info_stream_id: str,
chat_info_platform: str,
action_reasoning:str
):
self.action_id = action_id
self.time = time
@@ -234,3 +235,4 @@ class DatabaseActionRecords(BaseDataModel):
self.chat_id = chat_id
self.chat_info_stream_id = chat_info_stream_id
self.chat_info_platform = chat_info_platform
self.action_reasoning = action_reasoning

View File

@@ -24,3 +24,4 @@ class ActionPlannerInfo(BaseDataModel):
action_message: Optional["DatabaseMessages"] = None
available_actions: Optional[Dict[str, "ActionInfo"]] = None
loop_start_time: Optional[float] = None
action_reasoning: Optional[str] = None

View File

@@ -185,6 +185,8 @@ class ActionRecords(BaseModel):
action_id = TextField(index=True) # 消息 ID (更改自 IntegerField)
time = DoubleField() # 消息时间戳
action_reasoning = TextField(null=True)
action_name = TextField()
action_data = TextField()
action_done = BooleanField(default=False)

View File

@@ -406,7 +406,7 @@ MODULE_COLORS = {
"tts_action": "\033[38;5;58m", # 深黄色
"doubao_pic_plugin": "\033[38;5;64m", # 深绿色
# Action组件
"no_action_action": "\033[38;5;214m", # 亮橙色,显眼但不像警告
"no_reply_action": "\033[38;5;214m", # 亮橙色,显眼但不像警告
"reply_action": "\033[38;5;46m", # 亮绿色
"base_action": "\033[38;5;250m", # 浅灰色
# 数据库和消息

View File

@@ -309,6 +309,7 @@ async def store_action_info(
thinking_id: str = "",
action_data: Optional[dict] = None,
action_name: str = "",
action_reasoning: str = "",
) -> Optional[Dict[str, Any]]:
"""存储动作信息到数据库
@@ -322,7 +323,7 @@ async def store_action_info(
thinking_id: 关联的思考ID
action_data: 动作数据字典
action_name: 动作名称
action_reasoning: 动作执行理由
Returns:
Dict[str, Any]: 保存的记录数据
None: 如果保存失败
@@ -348,6 +349,7 @@ async def store_action_info(
"action_name": action_name,
"action_data": json.dumps(action_data or {}, ensure_ascii=False),
"action_done": action_done,
"action_reasoning": action_reasoning,
"action_build_into_prompt": action_build_into_prompt,
"action_prompt_display": action_prompt_display,
}

View File

@@ -34,11 +34,10 @@ class BaseAction(ABC):
def __init__(
self,
action_data: dict,
reasoning: str,
action_reasoning: str,
cycle_timers: dict,
thinking_id: str,
chat_stream: ChatStream,
log_prefix: str = "",
plugin_config: Optional[dict] = None,
action_message: Optional["DatabaseMessages"] = None,
**kwargs,
@@ -60,10 +59,11 @@ class BaseAction(ABC):
if plugin_config is None:
plugin_config = {}
self.action_data = action_data
self.reasoning = reasoning
self.reasoning = ""
self.cycle_timers = cycle_timers
self.thinking_id = thinking_id
self.log_prefix = log_prefix
self.action_reasoning = action_reasoning
self.plugin_config = plugin_config or {}
"""对应的插件配置"""
@@ -76,14 +76,6 @@ class BaseAction(ABC):
self.action_parameters: dict = getattr(self.__class__, "action_parameters", {}).copy()
self.action_require: list[str] = getattr(self.__class__, "action_require", []).copy()
# 设置激活类型实例属性(从类属性复制,提供默认值)
self.focus_activation_type = getattr(
self.__class__, "focus_activation_type", ActionActivationType.ALWAYS
) # 已弃用
"""FOCUS模式下的激活类型"""
self.normal_activation_type = getattr(
self.__class__, "normal_activation_type", ActionActivationType.ALWAYS
) # 已弃用
"""NORMAL模式下的激活类型"""
self.activation_type = getattr(self.__class__, "activation_type", self.focus_activation_type)
"""激活类型"""
@@ -115,44 +107,32 @@ class BaseAction(ABC):
self.user_nickname = None
self.is_group = False
self.target_id = None
self.has_action_message = False
if self.action_message:
self.has_action_message = True
if self.action_name != "no_action":
self.group_id = (
str(self.action_message.chat_info.group_info.group_id)
if self.action_message.chat_info.group_info
else None
)
self.group_name = (
self.action_message.chat_info.group_info.group_name
if self.action_message.chat_info.group_info
else None
)
self.group_id = (
str(self.action_message.chat_info.group_info.group_id)
if self.action_message.chat_info.group_info
else None
)
self.group_name = (
self.action_message.chat_info.group_info.group_name
if self.action_message.chat_info.group_info
else None
)
self.user_id = str(self.action_message.user_info.user_id)
self.user_nickname = self.action_message.user_info.user_nickname
if self.group_id:
self.is_group = True
self.target_id = self.group_id
self.log_prefix = f"[{self.group_name}]"
else:
self.is_group = False
self.target_id = self.user_id
self.log_prefix = f"[{self.user_nickname} 的 私聊]"
self.user_id = str(self.action_message.user_info.user_id)
self.user_nickname = self.action_message.user_info.user_nickname
if self.group_id:
self.is_group = True
self.target_id = self.group_id
else:
self.is_group = False
self.target_id = self.user_id
else:
if self.chat_stream.group_info:
self.group_id = self.chat_stream.group_info.group_id
self.group_name = self.chat_stream.group_info.group_name
self.is_group = True
self.target_id = self.group_id
else:
self.user_id = self.chat_stream.user_info.user_id
self.user_nickname = self.chat_stream.user_info.user_nickname
self.is_group = False
self.target_id = self.user_id
logger.debug(f"{self.log_prefix} Action组件初始化完成")
logger.debug(
f"{self.log_prefix} 聊天信息: 类型={'群聊' if self.is_group else '私聊'}, 平台={self.platform}, 目标={self.target_id}"
)
@@ -441,6 +421,7 @@ class BaseAction(ABC):
thinking_id=self.thinking_id,
action_data=self.action_data,
action_name=self.action_name,
action_reasoning=self.action_reasoning,
)
async def wait_for_new_message(self, timeout: int = 1200) -> Tuple[bool, str]:
@@ -467,11 +448,6 @@ class BaseAction(ABC):
wait_start_time = asyncio.get_event_loop().time()
while True:
# 检查关闭标志
# shutting_down = self.get_action_context("shutting_down", False)
# if shutting_down:
# logger.info(f"{self.log_prefix} 等待新消息时检测到关闭信号,中断等待")
# return False, ""
# 检查新消息
current_time = time.time()
@@ -530,8 +506,6 @@ class BaseAction(ABC):
name=name,
component_type=ComponentType.ACTION,
description=getattr(cls, "action_description", "Action动作"),
focus_activation_type=focus_activation_type,
normal_activation_type=normal_activation_type,
activation_type=activation_type,
activation_keywords=getattr(cls, "activation_keywords", []).copy(),
keyword_case_sensitive=getattr(cls, "keyword_case_sensitive", False),

View File

@@ -35,7 +35,7 @@ class CuriousAction(BaseAction):
# 动作参数定义
action_parameters = {
"question": "对存在疑问的信息提出一个问题,描述全面,使用无人称陈述句",
"question": "对存在疑问的信息提出一个问题,描述全面",
}
# 动作使用场景
@@ -64,7 +64,7 @@ class CuriousAction(BaseAction):
logger.info(f"已存储问题到冲突追踪器: {question}")
await self.store_action_info(
action_build_into_prompt=True,
action_prompt_display=f"你产生了一个问题:{question},尝试向其他人提问或回忆",
action_prompt_display=f"你产生了一个问题:{question},尝试向其他人提问或回忆",
action_done=True,
)
return True, "问题已记录"

View File

@@ -1,7 +1,7 @@
"""
核心动作插件
将系统核心动作reply、no_action、emoji转换为新插件系统格式
将系统核心动作reply、no_reply、emoji转换为新插件系统格式
这是系统的内置插件,提供基础的聊天交互功能
"""

View File

@@ -48,7 +48,7 @@ class MemoryBuildPlugin(BasePlugin):
# --- 根据配置注册组件 ---
components = []
components.append((GetMemoryAction.get_action_info(), GetMemoryAction))
# components.append((GetMemoryAction.get_action_info(), GetMemoryAction))
components.append((GetMemoryTool.get_tool_info(), GetMemoryTool))
return components