diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index dd71da7b1..2ccbe82bd 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -259,7 +259,7 @@ class HeartFChatting: gen_task = asyncio.create_task(self._generate_response(message_data, available_actions, reply_to_str)) with Timer("规划器", cycle_timers): - plan_result = await self.action_planner.plan(mode=self.loop_mode) + plan_result, target_message = await self.action_planner.plan(mode=self.loop_mode) action_result: dict = plan_result.get("action_result", {}) # type: ignore action_type, action_data, reasoning, is_parallel = ( @@ -310,10 +310,17 @@ class HeartFChatting: return True else: + + if message_data: + action_message = message_data + else: + action_message = target_message # 动作执行计时 + + with Timer("动作执行", cycle_timers): success, reply_text, command = await self._handle_action( - action_type, reasoning, action_data, cycle_timers, thinking_id + action_type, reasoning, action_data, cycle_timers, thinking_id, action_message ) loop_info = { @@ -367,6 +374,7 @@ class HeartFChatting: action_data: dict, cycle_timers: dict, thinking_id: str, + action_message: dict, ) -> tuple[bool, str, str]: """ 处理规划动作,使用动作工厂创建相应的动作处理器 @@ -392,6 +400,7 @@ class HeartFChatting: thinking_id=thinking_id, chat_stream=self.chat_stream, log_prefix=self.log_prefix, + action_message=action_message, ) except Exception as e: logger.error(f"{self.log_prefix} 创建动作处理器时出错: {e}") diff --git a/src/chat/planner_actions/action_manager.py b/src/chat/planner_actions/action_manager.py index 483ce9a3a..6c82625b3 100644 --- a/src/chat/planner_actions/action_manager.py +++ b/src/chat/planner_actions/action_manager.py @@ -80,6 +80,7 @@ class ActionManager: chat_stream: ChatStream, log_prefix: str, shutting_down: bool = False, + action_message: dict = None, ) -> Optional[BaseAction]: """ 创建动作处理器实例 @@ -125,6 +126,7 @@ class ActionManager: log_prefix=log_prefix, shutting_down=shutting_down, plugin_config=plugin_config, + action_message=action_message, ) logger.debug(f"创建Action实例成功: {action_name}") diff --git a/src/chat/planner_actions/planner.py b/src/chat/planner_actions/planner.py index 23f1d6948..6c865acd0 100644 --- a/src/chat/planner_actions/planner.py +++ b/src/chat/planner_actions/planner.py @@ -14,6 +14,7 @@ from src.chat.utils.chat_message_builder import ( build_readable_actions, get_actions_by_timestamp_with_chat, build_readable_messages, + build_readable_messages_with_id, get_raw_msg_before_timestamp_with_chat, ) from src.chat.utils.utils import get_chat_type_and_target_info @@ -39,14 +40,14 @@ def init_prompt(): {moderation_prompt} -现在请你根据{by_what}选择合适的action: +现在请你根据{by_what}选择合适的action和触发action的消息: 你刚刚选择并执行过的action是: {actions_before_now_block} {no_action_block} {action_options_text} -你必须从上面列出的可用action中选择一个,并说明原因。 +你必须从上面列出的可用action中选择一个,并说明触发action的消息id和原因。 请根据动作示例,以严格的 JSON 格式输出,且仅包含 JSON 内容: """, @@ -59,7 +60,8 @@ def init_prompt(): 动作描述:{action_description} {action_require} {{ - "action": "{action_name}",{action_parameters} + "action": "{action_name}",{action_parameters}{target_prompt} + "reason":"触发action的原因" }} """, "action_prompt", @@ -79,6 +81,22 @@ class ActionPlanner: self.last_obs_time_mark = 0.0 + def find_message_by_id(self, message_id: str, message_id_list: list) -> Optional[Dict[str, Any]]: + """ + 根据message_id从message_id_list中查找对应的原始消息 + + Args: + message_id: 要查找的消息ID + message_id_list: 消息ID列表,格式为[{'id': str, 'message': dict}, ...] + + Returns: + 找到的原始消息字典,如果未找到则返回None + """ + for item in message_id_list: + if item.get("id") == message_id: + return item.get("message") + return None + async def plan( self, mode: ChatMode = ChatMode.FOCUS ) -> Dict[str, Dict[str, Any] | str]: # sourcery skip: dict-comprehension @@ -125,7 +143,7 @@ class ActionPlanner: } # --- 构建提示词 (调用修改后的 PromptBuilder 方法) --- - prompt = await self.build_planner_prompt( + prompt, message_id_list = await self.build_planner_prompt( is_group_chat=is_group_chat, # <-- Pass HFC state chat_target_info=chat_target_info, # <-- 传递获取到的聊天目标信息 current_available_actions=current_available_actions, # <-- Pass determined actions @@ -176,6 +194,17 @@ class ActionPlanner: if key not in ["action", "reasoning"]: action_data[key] = value + # 在FOCUS模式下,非no_reply动作需要target_message_id + if mode == ChatMode.FOCUS and action != "no_reply": + target_message_id = parsed_json.get("target_message_id") + if target_message_id: + # 根据target_message_id查找原始消息 + target_message = self.find_message_by_id(target_message_id, message_id_list) + else: + logger.warning(f"{self.log_prefix}FOCUS模式下动作'{action}'缺少target_message_id") + else: + target_message = None + if action == "no_action": reasoning = "normal决定不使用额外动作" elif action != "no_reply" and action != "reply" and action not in current_available_actions: @@ -212,7 +241,7 @@ class ActionPlanner: return { "action_result": action_result, "action_prompt": prompt, - } + }, target_message async def build_planner_prompt( self, @@ -220,7 +249,7 @@ class ActionPlanner: chat_target_info: Optional[dict], # Now passed as argument current_available_actions: Dict[str, ActionInfo], mode: ChatMode = ChatMode.FOCUS, - ) -> str: # sourcery skip: use-join + ) -> tuple[str, list]: # sourcery skip: use-join """构建 Planner LLM 的提示词 (获取模板并填充数据)""" try: message_list_before_now = get_raw_msg_before_timestamp_with_chat( @@ -229,7 +258,7 @@ class ActionPlanner: limit=int(global_config.chat.max_context_size * 0.6), ) - chat_content_block = build_readable_messages( + chat_content_block, message_id_list = build_readable_messages_with_id( messages=message_list_before_now, timestamp_mode="normal_no_YMD", read_mark=self.last_obs_time_mark, @@ -251,6 +280,7 @@ class ActionPlanner: if mode == ChatMode.FOCUS: by_what = "聊天内容" + target_prompt = "\n \"target_message_id\":\"触发action的消息id\"" no_action_block = """重要说明1: - 'no_reply' 表示只进行不进行回复,等待合适的回复时机 - 当你刚刚发送了消息,没有人回复时,选择no_reply @@ -263,13 +293,13 @@ class ActionPlanner: - 如果你刚刚进行了回复,不要对同一个话题重复回应 { "action": "reply", - "reply_to":"你要回复的对方的发言内容,格式:(用户名:发言内容),可以为none" "reason":"回复的原因" } """ else: by_what = "聊天内容和用户的最新消息" + target_prompt = "" no_action_block = """重要说明: - 'no_action' 表示只进行普通聊天回复,不执行任何额外动作 - 其他action表示在普通回复的基础上,执行相应的额外动作""" @@ -304,6 +334,7 @@ class ActionPlanner: action_description=using_actions_info.description, action_parameters=param_text, action_require=require_text, + target_prompt=target_prompt, ) action_options_block += using_action_prompt @@ -321,7 +352,7 @@ class ActionPlanner: identity_block = f"你的名字是{bot_name}{bot_nickname},你{bot_core_personality}:" planner_prompt_template = await global_prompt_manager.get_prompt_async("planner_prompt") - return planner_prompt_template.format( + prompt = planner_prompt_template.format( time_block=time_block, by_what=by_what, chat_context_description=chat_context_description, @@ -332,10 +363,11 @@ class ActionPlanner: moderation_prompt=moderation_prompt_block, identity_block=identity_block, ) + return prompt, message_id_list except Exception as e: logger.error(f"构建 Planner 提示词时出错: {e}") logger.error(traceback.format_exc()) - return "构建 Planner Prompt 时出错" + return "构建 Planner Prompt 时出错", [] init_prompt() diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index 7da6ebc01..e3819f743 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -957,7 +957,7 @@ async def get_prompt_info(message: str, threshold: float): logger.debug("LPMM知识库已禁用,跳过知识获取") return "" - found_knowledge_from_lpmm = qa_manager.get_knowledge(message) + found_knowledge_from_lpmm = await qa_manager.get_knowledge(message) end_time = time.time() if found_knowledge_from_lpmm is not None: diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index 4f24eef88..4c0f032dd 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -10,7 +10,7 @@ from src.common.message_repository import find_messages, count_messages from src.common.database.database_model import ActionRecords from src.common.database.database_model import Images from src.person_info.person_info import PersonInfoManager, get_person_info_manager -from src.chat.utils.utils import translate_timestamp_to_human_readable +from src.chat.utils.utils import translate_timestamp_to_human_readable,assign_message_ids install(extra_lines=3) @@ -252,6 +252,7 @@ def _build_readable_messages_internal( pic_id_mapping: Optional[Dict[str, str]] = None, pic_counter: int = 1, show_pic: bool = True, + message_id_list: List[Dict[str, Any]] = [], ) -> Tuple[str, List[Tuple[float, str, str]], Dict[str, str], int]: """ 内部辅助函数,构建可读消息字符串和原始消息详情列表。 @@ -278,6 +279,15 @@ def _build_readable_messages_internal( pic_id_mapping = {} current_pic_counter = pic_counter + # 创建时间戳到消息ID的映射,用于在消息前添加[id]标识符 + timestamp_to_id = {} + if message_id_list: + for item in message_id_list: + message = item.get("message", {}) + timestamp = message.get("time") + if timestamp is not None: + timestamp_to_id[timestamp] = item.get("id", "") + def process_pic_ids(content: str) -> str: """处理内容中的图片ID,将其替换为[图片x]格式""" nonlocal current_pic_counter @@ -510,12 +520,16 @@ def _build_readable_messages_internal( # 使用指定的 timestamp_mode 格式化时间 readable_time = translate_timestamp_to_human_readable(merged["start_time"], mode=timestamp_mode) + # 查找对应的消息ID + message_id = timestamp_to_id.get(merged["start_time"], "") + id_prefix = f"[{message_id}] " if message_id else "" + # 检查是否是动作记录 if merged["is_action"]: # 对于动作记录,使用特殊格式 - output_lines.append(f"{readable_time}, {merged['content'][0]}") + output_lines.append(f"{id_prefix}{readable_time}, {merged['content'][0]}") else: - header = f"{readable_time}, {merged['name']} :" + header = f"{id_prefix}{readable_time}, {merged['name']} :" output_lines.append(header) # 将内容合并,并添加缩进 for line in merged["content"]: @@ -640,6 +654,39 @@ async def build_readable_messages_with_list( return formatted_string, details_list +def build_readable_messages_with_id( + messages: List[Dict[str, Any]], + replace_bot_name: bool = True, + merge_messages: bool = False, + timestamp_mode: str = "relative", + read_mark: float = 0.0, + truncate: bool = False, + show_actions: bool = False, + show_pic: bool = True, +) -> Tuple[str, List[Dict[str, Any]]]: + """ + 将消息列表转换为可读的文本格式,并返回原始(时间戳, 昵称, 内容)列表。 + 允许通过参数控制格式化行为。 + """ + message_id_list = assign_message_ids(messages) + + formatted_string = build_readable_messages( + messages = messages, + replace_bot_name=replace_bot_name, + merge_messages=merge_messages, + timestamp_mode=timestamp_mode, + truncate=truncate, + show_actions=show_actions, + show_pic=show_pic, + read_mark=read_mark, + message_id_list=message_id_list, + ) + + + + + return formatted_string , message_id_list + def build_readable_messages( messages: List[Dict[str, Any]], @@ -650,6 +697,7 @@ def build_readable_messages( truncate: bool = False, show_actions: bool = False, show_pic: bool = True, + message_id_list: List[Dict[str, Any]] = [], ) -> str: # sourcery skip: extract-method """ 将消息列表转换为可读的文本格式。 @@ -722,7 +770,7 @@ def build_readable_messages( if read_mark <= 0: # 没有有效的 read_mark,直接格式化所有消息 formatted_string, _, pic_id_mapping, _ = _build_readable_messages_internal( - copy_messages, replace_bot_name, merge_messages, timestamp_mode, truncate, show_pic=show_pic + copy_messages, replace_bot_name, merge_messages, timestamp_mode, truncate, show_pic=show_pic, message_id_list=message_id_list ) # 生成图片映射信息并添加到最前面 @@ -750,6 +798,7 @@ def build_readable_messages( pic_id_mapping, pic_counter, show_pic=show_pic, + message_id_list=message_id_list, ) formatted_after, _, pic_id_mapping, _ = _build_readable_messages_internal( messages_after_mark, @@ -760,6 +809,7 @@ def build_readable_messages( pic_id_mapping, pic_counter, show_pic=show_pic, + message_id_list=message_id_list, ) read_mark_line = "\n--- 以上消息是你已经看过,请关注以下未读的新消息---\n" diff --git a/src/chat/utils/utils.py b/src/chat/utils/utils.py index acc076f1b..a329b3548 100644 --- a/src/chat/utils/utils.py +++ b/src/chat/utils/utils.py @@ -1,12 +1,13 @@ import random import re +import string import time import jieba import numpy as np from collections import Counter from maim_message import UserInfo -from typing import Optional, Tuple, Dict +from typing import Optional, Tuple, Dict, List, Any from src.common.logger import get_logger from src.common.message_repository import find_messages, count_messages @@ -666,3 +667,107 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional[Dict]]: # Keep defaults on error return is_group_chat, chat_target_info + + +def assign_message_ids(messages: List[Any]) -> List[Dict[str, Any]]: + """ + 为消息列表中的每个消息分配唯一的简短随机ID + + Args: + messages: 消息列表 + + Returns: + 包含 {'id': str, 'message': any} 格式的字典列表 + """ + result = [] + used_ids = set() + len_i = len(messages) + if len_i > 100: + a = 10 + b = 99 + else: + a = 1 + b = 9 + + for i, message in enumerate(messages): + # 生成唯一的简短ID + while True: + # 使用索引+随机数生成简短ID + random_suffix = random.randint(a, b) + message_id = f"m{i+1}{random_suffix}" + + if message_id not in used_ids: + used_ids.add(message_id) + break + + result.append({ + 'id': message_id, + 'message': message + }) + + return result + + +def assign_message_ids_flexible( + messages: list, + prefix: str = "msg", + id_length: int = 6, + use_timestamp: bool = False +) -> list: + """ + 为消息列表中的每个消息分配唯一的简短随机ID(增强版) + + Args: + messages: 消息列表 + prefix: ID前缀,默认为"msg" + id_length: ID的总长度(不包括前缀),默认为6 + use_timestamp: 是否在ID中包含时间戳,默认为False + + Returns: + 包含 {'id': str, 'message': any} 格式的字典列表 + """ + result = [] + used_ids = set() + + for i, message in enumerate(messages): + # 生成唯一的ID + while True: + if use_timestamp: + # 使用时间戳的后几位 + 随机字符 + timestamp_suffix = str(int(time.time() * 1000))[-3:] + remaining_length = id_length - 3 + random_chars = ''.join(random.choices(string.ascii_lowercase + string.digits, k=remaining_length)) + message_id = f"{prefix}{timestamp_suffix}{random_chars}" + else: + # 使用索引 + 随机字符 + index_str = str(i + 1) + remaining_length = max(1, id_length - len(index_str)) + random_chars = ''.join(random.choices(string.ascii_lowercase + string.digits, k=remaining_length)) + message_id = f"{prefix}{index_str}{random_chars}" + + if message_id not in used_ids: + used_ids.add(message_id) + break + + result.append({ + 'id': message_id, + 'message': message + }) + + return result + + +# 使用示例: +# messages = ["Hello", "World", "Test message"] +# +# # 基础版本 +# result1 = assign_message_ids(messages) +# # 结果: [{'id': 'm1123', 'message': 'Hello'}, {'id': 'm2456', 'message': 'World'}, {'id': 'm3789', 'message': 'Test message'}] +# +# # 增强版本 - 自定义前缀和长度 +# result2 = assign_message_ids_flexible(messages, prefix="chat", id_length=8) +# # 结果: [{'id': 'chat1abc2', 'message': 'Hello'}, {'id': 'chat2def3', 'message': 'World'}, {'id': 'chat3ghi4', 'message': 'Test message'}] +# +# # 增强版本 - 使用时间戳 +# result3 = assign_message_ids_flexible(messages, prefix="ts", use_timestamp=True) +# # 结果: [{'id': 'ts123a1b', 'message': 'Hello'}, {'id': 'ts123c2d', 'message': 'World'}, {'id': 'ts123e3f', 'message': 'Test message'}] diff --git a/src/person_info/relationship_builder.py b/src/person_info/relationship_builder.py index c644d6e42..a489a34d5 100644 --- a/src/person_info/relationship_builder.py +++ b/src/person_info/relationship_builder.py @@ -377,7 +377,7 @@ class RelationshipBuilder: ): person_id = PersonInfoManager.get_person_id(platform, user_id) self._update_message_segments(person_id, msg_time) - logger.info( + logger.debug( f"{self.log_prefix} 更新用户 {person_id} 的消息段,消息时间:{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(msg_time))}" ) self.last_processed_message_time = max(self.last_processed_message_time, msg_time) @@ -395,7 +395,7 @@ class RelationshipBuilder: ) elif total_message_count > 0: # 记录进度信息 - logger.info( + logger.debug( f"{self.log_prefix} 用户 {person_name} 进度:{total_message_count}/60 条消息,{len(segments)} 个消息段" ) diff --git a/src/plugin_system/base/base_action.py b/src/plugin_system/base/base_action.py index 1649b431d..f0ad866b6 100644 --- a/src/plugin_system/base/base_action.py +++ b/src/plugin_system/base/base_action.py @@ -38,6 +38,7 @@ class BaseAction(ABC): chat_stream: ChatStream, log_prefix: str = "", plugin_config: Optional[dict] = None, + action_message: dict = None, **kwargs, ): """初始化Action组件 @@ -62,7 +63,7 @@ class BaseAction(ABC): self.cycle_timers = cycle_timers self.thinking_id = thinking_id self.log_prefix = log_prefix - + # 保存插件配置 self.plugin_config = plugin_config or {} @@ -89,38 +90,48 @@ class BaseAction(ABC): # 获取聊天流对象 self.chat_stream = chat_stream or kwargs.get("chat_stream") - self.chat_id = self.chat_stream.stream_id + self.platform = getattr(self.chat_stream, "platform", None) + # 初始化基础信息(带类型注解) - self.is_group: bool = False - self.platform: Optional[str] = None - self.group_id: Optional[str] = None - self.user_id: Optional[str] = None - self.target_id: Optional[str] = None - self.group_name: Optional[str] = None - self.user_nickname: Optional[str] = None - - # 如果有聊天流,提取所有信息 - if self.chat_stream: - self.platform = getattr(self.chat_stream, "platform", None) - - # 获取群聊信息 - # print(self.chat_stream) - # print(self.chat_stream.group_info) - if self.chat_stream.group_info: + self.action_message = action_message + + self.group_id = None + self.group_name = None + self.user_id = None + self.user_nickname = None + self.is_group = False + self.target_id = None + + + if self.action_name != "no_reply": + self.group_id = str(self.action_message.get("chat_info_group_id", None)) + self.group_name = self.action_message.get("chat_info_group_name", None) + + self.user_id = str(self.action_message.get("user_id", None)) + self.user_nickname = self.action_message.get("user_nickname", None) + if self.group_id: self.is_group = True - self.group_id = str(self.chat_stream.group_info.group_id) - self.group_name = getattr(self.chat_stream.group_info, "group_name", None) + self.target_id = self.group_id else: self.is_group = False - self.user_id = str(self.chat_stream.user_info.user_id) - self.user_nickname = getattr(self.chat_stream.user_info, "user_nickname", None) + 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 + - # 设置目标ID(群聊用群ID,私聊用户ID) - self.target_id = self.group_id if self.is_group else self.user_id logger.debug(f"{self.log_prefix} Action组件初始化完成") - logger.debug( + logger.info( f"{self.log_prefix} 聊天信息: 类型={'群聊' if self.is_group else '私聊'}, 平台={self.platform}, 目标={self.target_id}" ) diff --git a/src/plugins/built_in/core_actions/emoji.py b/src/plugins/built_in/core_actions/emoji.py index 59bc81dbe..1f1727adf 100644 --- a/src/plugins/built_in/core_actions/emoji.py +++ b/src/plugins/built_in/core_actions/emoji.py @@ -40,7 +40,7 @@ class EmojiAction(BaseAction): """ # 动作参数定义 - action_parameters = {"reason": "文字描述你想要发送的表情包原因"} + action_parameters = {} # 动作使用场景 action_require = [ diff --git a/src/plugins/built_in/core_actions/plugin.py b/src/plugins/built_in/core_actions/plugin.py index fdb376311..20241009e 100644 --- a/src/plugins/built_in/core_actions/plugin.py +++ b/src/plugins/built_in/core_actions/plugin.py @@ -24,6 +24,7 @@ from src.common.logger import get_logger 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 person_info_manager logger = get_logger("core_actions") @@ -45,10 +46,7 @@ class ReplyAction(BaseAction): action_description = "参与聊天回复,发送文本进行表达" # 动作参数定义 - action_parameters = { - "reply_to": "你要回复的对方的发言内容,格式:(用户名:发言内容),可以为none", - "reason": "回复的原因", - } + action_parameters = {} # 动作使用场景 action_require = ["你想要闲聊或者随便附和", "有人提到你", "如果你刚刚进行了回复,不要对同一个话题重复回应"] @@ -70,11 +68,14 @@ class ReplyAction(BaseAction): async def execute(self) -> Tuple[bool, str]: """执行回复动作""" logger.info(f"{self.log_prefix} 决定进行回复") - start_time = self.action_data.get("loop_start_time", time.time()) - reply_to = self.action_data.get("reply_to", "") - sender, target = self._parse_reply_target(reply_to) + user_id = self.user_id + platform = self.platform + person_id = person_info_manager.get_person_id(user_id, platform) + + person_name = person_info_manager.get_value(person_id, "person_name") + reply_to = f"{person_name}:{self.action_message.get('processed_plain_text', '')}" try: prepared_reply = self.action_data.get("prepared_reply", "") @@ -83,6 +84,7 @@ class ReplyAction(BaseAction): success, reply_set, _ = await asyncio.wait_for( generator_api.generate_reply( action_data=self.action_data, + reply_to=reply_to, chat_id=self.chat_id, request_type="chat.replyer.focus", enable_tool=global_config.tool.enable_in_focus_chat, @@ -115,7 +117,7 @@ class ReplyAction(BaseAction): data = reply_seg[1] if not first_replied: if need_reply: - await self.send_text(content=data, reply_to=self.action_data.get("reply_to", ""), typing=False) + await self.send_text(content=data, reply_to=reply_to, typing=False) first_replied = True else: await self.send_text(content=data, typing=False) @@ -125,10 +127,7 @@ class ReplyAction(BaseAction): reply_text += data # 存储动作记录 - if sender and target: - reply_text = f"你对{sender}说的{target},进行了回复:{reply_text}" - else: - reply_text = f"你进行发言:{reply_text}" + reply_text = f"你对{person_name}进行了回复:{reply_text}" await self.store_action_info( action_build_into_prompt=False,