🤖 自动格式化代码 [skip ci]

This commit is contained in:
github-actions[bot]
2025-07-06 12:17:38 +00:00
parent 7bff29eb28
commit 18778d2dc7
11 changed files with 34 additions and 45 deletions

View File

@@ -19,7 +19,6 @@ async def forced_change_subheartflow_status(subheartflow_id: str, status: ChatSt
return False return False
async def get_all_states(): async def get_all_states():
"""获取所有状态""" """获取所有状态"""
all_states = await heartflow.api_get_all_states() all_states = await heartflow.api_get_all_states()

View File

@@ -76,7 +76,6 @@ class FocusLoopInfo:
else: else:
cycle_info_block = "\n" cycle_info_block = "\n"
# 获取history_loop中最新添加的 # 获取history_loop中最新添加的
if self.history_loop: if self.history_loop:
last_loop = self.history_loop[0] last_loop = self.history_loop[0]
@@ -89,4 +88,4 @@ class FocusLoopInfo:
else: else:
cycle_info_block += f"距离你上一次阅读消息并思考和规划,已经过去了{time_diff}\n" cycle_info_block += f"距离你上一次阅读消息并思考和规划,已经过去了{time_diff}\n"
else: else:
cycle_info_block += "你还没看过消息\n" cycle_info_block += "你还没看过消息\n"

View File

@@ -26,6 +26,7 @@ install(extra_lines=3)
logger = get_logger("hfc") # Logger Name Changed logger = get_logger("hfc") # Logger Name Changed
class HeartFChatting: class HeartFChatting:
""" """
管理一个连续的Focus Chat循环 管理一个连续的Focus Chat循环
@@ -63,10 +64,7 @@ class HeartFChatting:
self.loop_info: FocusLoopInfo = FocusLoopInfo(observe_id=self.stream_id) self.loop_info: FocusLoopInfo = FocusLoopInfo(observe_id=self.stream_id)
self.action_manager = ActionManager() self.action_manager = ActionManager()
self.action_planner = ActionPlanner( self.action_planner = ActionPlanner(chat_id=self.stream_id, action_manager=self.action_manager)
chat_id = self.stream_id,
action_manager=self.action_manager
)
self.action_modifier = ActionModifier(action_manager=self.action_manager, chat_id=self.stream_id) self.action_modifier = ActionModifier(action_manager=self.action_manager, chat_id=self.stream_id)
self._processing_lock = asyncio.Lock() self._processing_lock = asyncio.Lock()
@@ -238,7 +236,6 @@ class HeartFChatting:
self._current_cycle_detail.set_loop_info(loop_info) self._current_cycle_detail.set_loop_info(loop_info)
self.loop_info.add_loop_info(self._current_cycle_detail) self.loop_info.add_loop_info(self._current_cycle_detail)
self._current_cycle_detail.timers = cycle_timers self._current_cycle_detail.timers = cycle_timers
@@ -253,7 +250,6 @@ class HeartFChatting:
formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}" formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}"
timer_strings.append(f"{name}: {formatted_time}") timer_strings.append(f"{name}: {formatted_time}")
logger.info( logger.info(
f"{self.log_prefix}{self._current_cycle_detail.cycle_id}次思考," f"{self.log_prefix}{self._current_cycle_detail.cycle_id}次思考,"
f"耗时: {self._current_cycle_detail.end_time - self._current_cycle_detail.start_time:.1f}秒, " f"耗时: {self._current_cycle_detail.end_time - self._current_cycle_detail.start_time:.1f}秒, "
@@ -275,7 +271,7 @@ class HeartFChatting:
self.performance_logger.record_cycle(cycle_performance_data) self.performance_logger.record_cycle(cycle_performance_data)
except Exception as perf_e: except Exception as perf_e:
logger.warning(f"{self.log_prefix} 记录性能数据失败: {perf_e}") logger.warning(f"{self.log_prefix} 记录性能数据失败: {perf_e}")
await asyncio.sleep(global_config.focus_chat.think_interval) await asyncio.sleep(global_config.focus_chat.think_interval)
except asyncio.CancelledError: except asyncio.CancelledError:
@@ -352,7 +348,7 @@ class HeartFChatting:
try: try:
# 调用完整的动作修改流程 # 调用完整的动作修改流程
await self.action_modifier.modify_actions( await self.action_modifier.modify_actions(
loop_info = self.loop_info, loop_info=self.loop_info,
mode="focus", mode="focus",
) )
except Exception as e: except Exception as e:
@@ -371,7 +367,7 @@ class HeartFChatting:
plan_result.get("action_result", {}).get("action_data", {}), plan_result.get("action_result", {}).get("action_data", {}),
plan_result.get("action_result", {}).get("reasoning", "未提供理由"), plan_result.get("action_result", {}).get("reasoning", "未提供理由"),
) )
action_data["loop_start_time"] = loop_start_time action_data["loop_start_time"] = loop_start_time
if action_type == "reply": if action_type == "reply":

View File

@@ -104,7 +104,6 @@ class CycleDetail:
self.loop_action_info = loop_info["loop_action_info"] self.loop_action_info = loop_info["loop_action_info"]
async def create_empty_anchor_message( async def create_empty_anchor_message(
platform: str, group_info: dict, chat_stream: ChatStream platform: str, group_info: dict, chat_stream: ChatStream
) -> Optional[MessageRecv]: ) -> Optional[MessageRecv]:

View File

@@ -7,6 +7,7 @@ class ChatState(enum.Enum):
NORMAL = "随便水群" NORMAL = "随便水群"
FOCUSED = "认真水群" FOCUSED = "认真水群"
class ChatStateInfo: class ChatStateInfo:
def __init__(self): def __init__(self):
self.chat_status: ChatState = ChatState.NORMAL self.chat_status: ChatState = ChatState.NORMAL

View File

@@ -3,6 +3,7 @@ from src.common.logger import get_logger
from typing import Any, Optional from typing import Any, Optional
from typing import Dict from typing import Dict
from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.chat_stream import get_chat_manager
logger = get_logger("heartflow") logger = get_logger("heartflow")
@@ -36,12 +37,11 @@ class Heartflow:
logger.error(f"创建子心流 {subheartflow_id} 失败: {e}", exc_info=True) logger.error(f"创建子心流 {subheartflow_id} 失败: {e}", exc_info=True)
return None return None
async def force_change_subheartflow_status(self, subheartflow_id: str, status: ChatState) -> None: async def force_change_subheartflow_status(self, subheartflow_id: str, status: ChatState) -> None:
"""强制改变子心流的状态""" """强制改变子心流的状态"""
# 这里的 message 是可选的,可能是一个消息对象,也可能是其他类型的数据 # 这里的 message 是可选的,可能是一个消息对象,也可能是其他类型的数据
return await self.force_change_state(subheartflow_id, status) return await self.force_change_state(subheartflow_id, status)
async def force_change_state(self, subflow_id: Any, target_state: ChatState) -> bool: async def force_change_state(self, subflow_id: Any, target_state: ChatState) -> bool:
"""强制改变指定子心流的状态""" """强制改变指定子心流的状态"""
subflow = self.subheartflows.get(subflow_id) subflow = self.subheartflows.get(subflow_id)

View File

@@ -17,6 +17,7 @@ from src.person_info.relationship_manager import get_relationship_manager
logger = get_logger("chat") logger = get_logger("chat")
async def _process_relationship(message: MessageRecv) -> None: async def _process_relationship(message: MessageRecv) -> None:
"""处理用户关系逻辑 """处理用户关系逻辑

View File

@@ -43,7 +43,7 @@ class ActionModifier:
async def modify_actions( async def modify_actions(
self, self,
loop_info = None, loop_info=None,
mode: str = "focus", mode: str = "focus",
message_content: str = "", message_content: str = "",
): ):
@@ -60,10 +60,10 @@ class ActionModifier:
removals_s1 = [] removals_s1 = []
removals_s2 = [] removals_s2 = []
self.action_manager.restore_actions() self.action_manager.restore_actions()
all_actions = self.action_manager.get_using_actions_for_mode(mode) all_actions = self.action_manager.get_using_actions_for_mode(mode)
message_list_before_now_half = get_raw_msg_before_timestamp_with_chat( message_list_before_now_half = get_raw_msg_before_timestamp_with_chat(
chat_id=self.chat_stream.stream_id, chat_id=self.chat_stream.stream_id,
timestamp=time.time(), timestamp=time.time(),
@@ -77,7 +77,7 @@ class ActionModifier:
read_mark=0.0, read_mark=0.0,
show_actions=True, show_actions=True,
) )
if message_content: if message_content:
chat_content = chat_content + "\n" + f"现在,最新的消息是:{message_content}" chat_content = chat_content + "\n" + f"现在,最新的消息是:{message_content}"
@@ -99,14 +99,13 @@ class ActionModifier:
self.action_manager.remove_action_from_using(action_name) self.action_manager.remove_action_from_using(action_name)
logger.debug(f"{self.log_prefix}阶段一移除动作: {action_name},原因: {reason}") logger.debug(f"{self.log_prefix}阶段一移除动作: {action_name},原因: {reason}")
# === 第二阶段:激活类型判定 === # === 第二阶段:激活类型判定 ===
if chat_content is not None: if chat_content is not None:
logger.debug(f"{self.log_prefix}开始激活类型判定阶段") logger.debug(f"{self.log_prefix}开始激活类型判定阶段")
# 获取当前使用的动作集(经过第一阶段处理) # 获取当前使用的动作集(经过第一阶段处理)
current_using_actions = self.action_manager.get_using_actions_for_mode(mode) current_using_actions = self.action_manager.get_using_actions_for_mode(mode)
# 获取因激活类型判定而需要移除的动作 # 获取因激活类型判定而需要移除的动作
removals_s2 = await self._get_deactivated_actions_by_type( removals_s2 = await self._get_deactivated_actions_by_type(
current_using_actions, current_using_actions,
@@ -118,7 +117,7 @@ class ActionModifier:
for action_name, reason in removals_s2: for action_name, reason in removals_s2:
self.action_manager.remove_action_from_using(action_name) self.action_manager.remove_action_from_using(action_name)
logger.debug(f"{self.log_prefix}阶段二移除动作: {action_name},原因: {reason}") logger.debug(f"{self.log_prefix}阶段二移除动作: {action_name},原因: {reason}")
# === 统一日志记录 === # === 统一日志记录 ===
all_removals = removals_s1 + removals_s2 all_removals = removals_s1 + removals_s2
if all_removals: if all_removals:
@@ -136,11 +135,9 @@ class ActionModifier:
associated_types_str = ", ".join(data["associated_types"]) associated_types_str = ", ".join(data["associated_types"])
reason = f"适配器不支持(需要: {associated_types_str}" reason = f"适配器不支持(需要: {associated_types_str}"
type_mismatched_actions.append((action_name, reason)) type_mismatched_actions.append((action_name, reason))
logger.debug( logger.debug(f"{self.log_prefix}决定移除动作: {action_name},原因: {reason}")
f"{self.log_prefix}决定移除动作: {action_name},原因: {reason}"
)
return type_mismatched_actions return type_mismatched_actions
async def _get_deactivated_actions_by_type( async def _get_deactivated_actions_by_type(
self, self,
actions_with_info: Dict[str, Any], actions_with_info: Dict[str, Any],
@@ -161,7 +158,7 @@ class ActionModifier:
# 分类处理不同激活类型的actions # 分类处理不同激活类型的actions
llm_judge_actions = {} llm_judge_actions = {}
actions_to_check = list(actions_with_info.items()) actions_to_check = list(actions_with_info.items())
random.shuffle(actions_to_check) random.shuffle(actions_to_check)
@@ -188,7 +185,7 @@ class ActionModifier:
elif activation_type == "llm_judge": elif activation_type == "llm_judge":
llm_judge_actions[action_name] = action_info llm_judge_actions[action_name] = action_info
else: else:
logger.warning(f"{self.log_prefix}未知的激活类型: {activation_type},跳过处理") logger.warning(f"{self.log_prefix}未知的激活类型: {activation_type},跳过处理")
@@ -512,21 +509,23 @@ class ActionModifier:
# 如果最近sec_thres_reply_num次都是reply40%概率移除 # 如果最近sec_thres_reply_num次都是reply40%概率移除
removal_probability = 0.4 / global_config.focus_chat.consecutive_replies removal_probability = 0.4 / global_config.focus_chat.consecutive_replies
if random.random() < removal_probability: if random.random() < removal_probability:
reason = f"连续回复较多(最近{sec_thres_reply_num}次全是reply{removal_probability:.2f}概率移除,触发移除)" reason = (
f"连续回复较多(最近{sec_thres_reply_num}次全是reply{removal_probability:.2f}概率移除,触发移除)"
)
removals.append(("reply", reason)) removals.append(("reply", reason))
elif len(last_max_reply_num) >= one_thres_reply_num and all(last_max_reply_num[-one_thres_reply_num:]): elif len(last_max_reply_num) >= one_thres_reply_num and all(last_max_reply_num[-one_thres_reply_num:]):
# 如果最近one_thres_reply_num次都是reply20%概率移除 # 如果最近one_thres_reply_num次都是reply20%概率移除
removal_probability = 0.2 / global_config.focus_chat.consecutive_replies removal_probability = 0.2 / global_config.focus_chat.consecutive_replies
if random.random() < removal_probability: if random.random() < removal_probability:
reason = f"连续回复检测(最近{one_thres_reply_num}次全是reply{removal_probability:.2f}概率移除,触发移除)" reason = (
f"连续回复检测(最近{one_thres_reply_num}次全是reply{removal_probability:.2f}概率移除,触发移除)"
)
removals.append(("reply", reason)) removals.append(("reply", reason))
else: else:
logger.debug(f"{self.log_prefix}连续回复检测无需移除reply动作最近回复模式正常") logger.debug(f"{self.log_prefix}连续回复检测无需移除reply动作最近回复模式正常")
return removals return removals
def get_available_actions_count(self) -> int: def get_available_actions_count(self) -> int:
"""获取当前可用动作数量排除默认的no_action""" """获取当前可用动作数量排除默认的no_action"""
current_actions = self.action_manager.get_using_actions_for_mode("normal") current_actions = self.action_manager.get_using_actions_for_mode("normal")
@@ -540,4 +539,4 @@ class ActionModifier:
if available_count == 0: if available_count == 0:
logger.debug(f"{self.log_prefix} 没有可用动作,跳过规划") logger.debug(f"{self.log_prefix} 没有可用动作,跳过规划")
return True return True
return False return False

View File

@@ -55,7 +55,7 @@ class ActionPlanner:
def __init__(self, chat_id: str, action_manager: ActionManager): def __init__(self, chat_id: str, action_manager: ActionManager):
self.chat_id = chat_id self.chat_id = chat_id
self.log_prefix = f"[{get_chat_manager().get_stream_name(chat_id) or chat_id}]" self.log_prefix = f"[{get_chat_manager().get_stream_name(chat_id) or chat_id}]"
self.action_manager = action_manager self.action_manager = action_manager
# LLM规划器配置 # LLM规划器配置
self.planner_llm = LLMRequest( self.planner_llm = LLMRequest(
@@ -67,7 +67,7 @@ class ActionPlanner:
model=global_config.model.utils_small, model=global_config.model.utils_small,
request_type="focus.planner", # 用于动作规划 request_type="focus.planner", # 用于动作规划
) )
self.last_obs_time_mark = 0.0 self.last_obs_time_mark = 0.0
async def plan(self) -> Dict[str, Any]: async def plan(self) -> Dict[str, Any]:
@@ -81,7 +81,7 @@ class ActionPlanner:
try: try:
is_group_chat = True is_group_chat = True
message_list_before_now = get_raw_msg_before_timestamp_with_chat( message_list_before_now = get_raw_msg_before_timestamp_with_chat(
chat_id=self.chat_id, chat_id=self.chat_id,
timestamp=time.time(), timestamp=time.time(),
@@ -95,7 +95,7 @@ class ActionPlanner:
truncate=True, truncate=True,
show_actions=True, show_actions=True,
) )
self.last_obs_time_mark = time.time() self.last_obs_time_mark = time.time()
# 获取聊天类型和目标信息 # 获取聊天类型和目标信息
@@ -104,9 +104,7 @@ class ActionPlanner:
try: try:
# 重新获取更准确的聊天信息 # 重新获取更准确的聊天信息
is_group_chat, chat_target_info = get_chat_type_and_target_info(self.chat_id) is_group_chat, chat_target_info = get_chat_type_and_target_info(self.chat_id)
logger.debug( logger.debug(f"{self.log_prefix}获取到聊天信息 - 群聊: {is_group_chat}, 目标信息: {chat_target_info}")
f"{self.log_prefix}获取到聊天信息 - 群聊: {is_group_chat}, 目标信息: {chat_target_info}"
)
except Exception as e: except Exception as e:
logger.warning(f"{self.log_prefix}获取聊天目标信息失败: {e}") logger.warning(f"{self.log_prefix}获取聊天目标信息失败: {e}")
chat_target_info = None chat_target_info = None
@@ -201,7 +199,6 @@ class ActionPlanner:
if key not in ["action", "reasoning"]: if key not in ["action", "reasoning"]:
action_data[key] = value action_data[key] = value
if extracted_action not in current_available_actions: if extracted_action not in current_available_actions:
logger.warning( logger.warning(
f"{self.log_prefix}LLM 返回了当前不可用或无效的动作: '{extracted_action}' (可用: {list(current_available_actions.keys())}),将强制使用 'no_reply'" f"{self.log_prefix}LLM 返回了当前不可用或无效的动作: '{extracted_action}' (可用: {list(current_available_actions.keys())}),将强制使用 'no_reply'"
@@ -266,8 +263,6 @@ class ActionPlanner:
action_options_block = "" action_options_block = ""
for using_actions_name, using_actions_info in current_available_actions.items(): for using_actions_name, using_actions_info in current_available_actions.items():
if using_actions_info["parameters"]: if using_actions_info["parameters"]:
param_text = "\n" param_text = "\n"
for param_name, param_description in using_actions_info["parameters"].items(): for param_name, param_description in using_actions_info["parameters"].items():

View File

@@ -642,6 +642,7 @@ def translate_timestamp_to_human_readable(timestamp: float, mode: str = "normal"
# 只返回时分秒格式,喵~ # 只返回时分秒格式,喵~
return time.strftime("%H:%M:%S", time.localtime(timestamp)) return time.strftime("%H:%M:%S", time.localtime(timestamp))
def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional[Dict]]: def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional[Dict]]:
""" """
获取聊天类型(是否群聊)和私聊对象信息。 获取聊天类型(是否群聊)和私聊对象信息。
@@ -706,4 +707,4 @@ def get_chat_type_and_target_info(chat_id: str) -> Tuple[bool, Optional[Dict]]:
logger.error(f"获取聊天类型和目标信息时出错 for {chat_id}: {e}", exc_info=True) logger.error(f"获取聊天类型和目标信息时出错 for {chat_id}: {e}", exc_info=True)
# Keep defaults on error # Keep defaults on error
return is_group_chat, chat_target_info return is_group_chat, chat_target_info

View File

@@ -300,7 +300,6 @@ class FocusChatConfig(ConfigBase):
"""连续回复能力,值越高,麦麦连续回复的概率越高""" """连续回复能力,值越高,麦麦连续回复的概率越高"""
@dataclass @dataclass
class ExpressionConfig(ConfigBase): class ExpressionConfig(ConfigBase):
"""表达配置类""" """表达配置类"""