feat:不再需要reply_to,action现拥有 user_id和group_id等信息
This commit is contained in:
@@ -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}")
|
||||
|
||||
@@ -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}")
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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'}]
|
||||
|
||||
@@ -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)} 个消息段"
|
||||
)
|
||||
|
||||
|
||||
@@ -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}"
|
||||
)
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class EmojiAction(BaseAction):
|
||||
"""
|
||||
|
||||
# 动作参数定义
|
||||
action_parameters = {"reason": "文字描述你想要发送的表情包原因"}
|
||||
action_parameters = {}
|
||||
|
||||
# 动作使用场景
|
||||
action_require = [
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user