feat;更改了talk_value的含义,增加私聊模式
This commit is contained in:
@@ -50,16 +50,6 @@ ERROR_LOOP_INFO = {
|
||||
},
|
||||
}
|
||||
|
||||
# ?什么时候发言:
|
||||
# 1.聊天频率较低:与过去该时段发言频率进行比较
|
||||
# 2.感兴趣的话题:暂时使用Emb计算
|
||||
# 3.感兴趣的人:认识次数
|
||||
# 4.直接提及
|
||||
|
||||
# 什么时候不发言:
|
||||
# 1.敏感话题:判断较难
|
||||
# 2.发言频率太高:近时判断,例如发言频率> 1/人数 *2
|
||||
# 3.明确被拒绝:planner判断
|
||||
|
||||
install(extra_lines=3)
|
||||
|
||||
@@ -106,7 +96,7 @@ class HeartFChatting:
|
||||
self._cycle_counter = 0
|
||||
self._current_cycle_detail: CycleDetail = None # type: ignore
|
||||
|
||||
self.last_read_time = time.time() - 10
|
||||
self.last_read_time = time.time() - 2
|
||||
|
||||
self.talk_threshold = global_config.chat.talk_value
|
||||
|
||||
@@ -172,16 +162,6 @@ class HeartFChatting:
|
||||
+ (f"\n详情: {'; '.join(timer_strings)}" if timer_strings else "")
|
||||
)
|
||||
|
||||
def get_talk_threshold(self):
|
||||
talk_value = global_config.chat.talk_value
|
||||
# 处理talk_value:取整数部分和小数部分
|
||||
base_value = int(talk_value)
|
||||
probability = talk_value - base_value
|
||||
# 根据概率决定是否+1
|
||||
think_len = base_value + 1 if random.random() < probability else base_value
|
||||
self.talk_threshold = think_len
|
||||
logger.info(f"{self.log_prefix} 思考频率阈值: {self.talk_threshold}")
|
||||
|
||||
async def _loopbody(self): # sourcery skip: hoist-if-from-if
|
||||
recent_messages_list = message_api.get_messages_by_time_in_chat(
|
||||
chat_id=self.stream_id,
|
||||
@@ -193,7 +173,7 @@ class HeartFChatting:
|
||||
filter_command=True,
|
||||
)
|
||||
|
||||
if len(recent_messages_list) >= self.talk_threshold:
|
||||
if len(recent_messages_list) >= 1:
|
||||
# !处理no_reply_until_call逻辑
|
||||
if self.no_reply_until_call:
|
||||
for message in recent_messages_list:
|
||||
@@ -212,10 +192,21 @@ class HeartFChatting:
|
||||
return True
|
||||
|
||||
self.last_read_time = time.time()
|
||||
|
||||
# !此处使at或者提及必定回复
|
||||
metioned_message = None
|
||||
for message in recent_messages_list:
|
||||
if (message.is_mentioned or message.is_at) and global_config.chat.mentioned_bot_reply:
|
||||
metioned_message = message
|
||||
|
||||
# *控制频率用
|
||||
if not metioned_message:
|
||||
if random.random() > global_config.chat.talk_value:
|
||||
return True
|
||||
|
||||
await self._observe(
|
||||
recent_messages_list=recent_messages_list,
|
||||
recent_messages_list=recent_messages_list,force_reply_message=metioned_message
|
||||
)
|
||||
self.get_talk_threshold()
|
||||
else:
|
||||
# Normal模式:消息数量不足,等待
|
||||
await asyncio.sleep(0.2)
|
||||
@@ -274,7 +265,7 @@ class HeartFChatting:
|
||||
|
||||
async def _observe(
|
||||
self, # interest_value: float = 0.0,
|
||||
recent_messages_list: Optional[List["DatabaseMessages"]] = None,
|
||||
recent_messages_list: Optional[List["DatabaseMessages"]] = None, force_reply_message:"DatabaseMessages" = None
|
||||
) -> bool: # sourcery skip: merge-else-if-into-elif, remove-redundant-if
|
||||
if recent_messages_list is None:
|
||||
recent_messages_list = []
|
||||
@@ -335,25 +326,19 @@ class HeartFChatting:
|
||||
available_actions=available_actions,
|
||||
)
|
||||
|
||||
# !此处使at或者提及必定回复
|
||||
metioned_message = None
|
||||
for message in recent_messages_list:
|
||||
if (message.is_mentioned or message.is_at) and global_config.chat.mentioned_bot_reply:
|
||||
metioned_message = message
|
||||
|
||||
has_reply = False
|
||||
for action in action_to_use_info:
|
||||
if action.action_type == "reply":
|
||||
has_reply = True
|
||||
break
|
||||
|
||||
if not has_reply and metioned_message:
|
||||
if not has_reply and force_reply_message:
|
||||
action_to_use_info.append(
|
||||
ActionPlannerInfo(
|
||||
action_type="reply",
|
||||
reasoning="有人提到了你,进行回复",
|
||||
action_data={},
|
||||
action_message=metioned_message,
|
||||
action_message=force_reply_message,
|
||||
available_actions=available_actions,
|
||||
)
|
||||
)
|
||||
@@ -556,92 +541,94 @@ class HeartFChatting:
|
||||
):
|
||||
"""执行单个动作的通用函数"""
|
||||
try:
|
||||
if action_planner_info.action_type == "no_reply":
|
||||
# 直接处理no_action逻辑,不再通过动作系统
|
||||
reason = action_planner_info.reasoning or "选择不回复"
|
||||
logger.info(f"{self.log_prefix} 选择不回复,原因: {reason}")
|
||||
with Timer(f"动作{action_planner_info.action_type}", cycle_timers):
|
||||
|
||||
if action_planner_info.action_type == "no_reply":
|
||||
# 直接处理no_action逻辑,不再通过动作系统
|
||||
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",
|
||||
)
|
||||
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": ""}
|
||||
|
||||
elif action_planner_info.action_type == "no_reply_until_call":
|
||||
logger.info(f"{self.log_prefix} 保持沉默,直到有人直接叫的名字")
|
||||
self.no_reply_until_call = True
|
||||
return {"action_type": "no_reply_until_call", "success": True, "reply_text": "", "command": ""}
|
||||
|
||||
elif action_planner_info.action_type == "reply":
|
||||
try:
|
||||
success, llm_response = await generator_api.generate_reply(
|
||||
# 存储no_action信息到数据库
|
||||
await database_api.store_action_info(
|
||||
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 "",
|
||||
enable_tool=global_config.tool.enable_tool,
|
||||
request_type="replyer",
|
||||
from_plugin=False,
|
||||
action_build_into_prompt=False,
|
||||
action_prompt_display=reason,
|
||||
action_done=True,
|
||||
thinking_id=thinking_id,
|
||||
action_data={"reason": reason},
|
||||
action_name="no_action",
|
||||
)
|
||||
return {"action_type": "no_action", "success": True, "reply_text": "", "command": ""}
|
||||
|
||||
if not success or not llm_response or not llm_response.reply_set:
|
||||
if action_planner_info.action_message:
|
||||
logger.info(f"对 {action_planner_info.action_message.processed_plain_text} 的回复生成失败")
|
||||
else:
|
||||
logger.info("回复生成失败")
|
||||
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": ""}
|
||||
|
||||
elif action_planner_info.action_type == "no_reply_until_call":
|
||||
logger.info(f"{self.log_prefix} 保持沉默,直到有人直接叫的名字")
|
||||
self.no_reply_until_call = True
|
||||
return {"action_type": "no_reply_until_call", "success": True, "reply_text": "", "command": ""}
|
||||
|
||||
elif action_planner_info.action_type == "reply":
|
||||
try:
|
||||
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 "",
|
||||
enable_tool=global_config.tool.enable_tool,
|
||||
request_type="replyer",
|
||||
from_plugin=False,
|
||||
)
|
||||
|
||||
if not success or not llm_response or not llm_response.reply_set:
|
||||
if action_planner_info.action_message:
|
||||
logger.info(f"对 {action_planner_info.action_message.processed_plain_text} 的回复生成失败")
|
||||
else:
|
||||
logger.info("回复生成失败")
|
||||
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
||||
|
||||
except asyncio.CancelledError:
|
||||
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
||||
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
||||
|
||||
except asyncio.CancelledError:
|
||||
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
|
||||
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
|
||||
response_set = llm_response.reply_set
|
||||
selected_expressions = llm_response.selected_expressions
|
||||
loop_info, reply_text, _ = await self._send_and_store_reply(
|
||||
response_set=response_set,
|
||||
action_message=action_planner_info.action_message, # type: ignore
|
||||
cycle_timers=cycle_timers,
|
||||
thinking_id=thinking_id,
|
||||
actions=chosen_action_plan_infos,
|
||||
selected_expressions=selected_expressions,
|
||||
)
|
||||
return {
|
||||
"action_type": "reply",
|
||||
"success": True,
|
||||
"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,
|
||||
response_set = llm_response.reply_set
|
||||
selected_expressions = llm_response.selected_expressions
|
||||
loop_info, reply_text, _ = await self._send_and_store_reply(
|
||||
response_set=response_set,
|
||||
action_message=action_planner_info.action_message, # type: ignore
|
||||
cycle_timers=cycle_timers,
|
||||
thinking_id=thinking_id,
|
||||
actions=chosen_action_plan_infos,
|
||||
selected_expressions=selected_expressions,
|
||||
)
|
||||
return {
|
||||
"action_type": action_planner_info.action_type,
|
||||
"success": success,
|
||||
"reply_text": reply_text,
|
||||
"command": command,
|
||||
}
|
||||
return {
|
||||
"action_type": "reply",
|
||||
"success": True,
|
||||
"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,
|
||||
)
|
||||
return {
|
||||
"action_type": action_planner_info.action_type,
|
||||
"success": success,
|
||||
"reply_text": reply_text,
|
||||
"command": command,
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"{self.log_prefix} 执行动作时出错: {e}")
|
||||
|
||||
Reference in New Issue
Block a user