docs(core): 为核心模块添加日志记录和文档字符串

为 `cycle_processor`, `response_handler`, `generator_api`, 和 `send_api` 等核心代码文件补充了日志记录器和详细的文档字符串(docstrings)。

本次更新旨在提高代码的可读性和可维护性,通过清晰的文档注释和日志输出,使其他开发者能更容易地理解代码逻辑和功能,并为未来的调试和功能扩展提供便利。
This commit is contained in:
minecraft1024a
2025-09-06 15:52:21 +08:00
parent fd5d951501
commit a3d0588e7e
4 changed files with 84 additions and 3 deletions

View File

@@ -19,10 +19,14 @@ from .hfc_context import HfcContext
from .response_handler import ResponseHandler
from .cycle_tracker import CycleTracker
# 日志记录器
logger = get_logger("hfc.processor")
class CycleProcessor:
"""
循环处理器类,负责处理单次思考循环的逻辑。
"""
def __init__(self, context: HfcContext, response_handler: ResponseHandler, cycle_tracker: CycleTracker):
"""
初始化循环处理器
@@ -51,14 +55,30 @@ class CycleProcessor:
thinking_id,
actions,
) -> Tuple[Dict[str, Any], str, Dict[str, float]]:
"""
发送并存储回复信息
Args:
response_set: 回复内容集合
loop_start_time: 循环开始时间
action_message: 动作消息
cycle_timers: 循环计时器
thinking_id: 思考ID
actions: 动作列表
Returns:
Tuple[Dict[str, Any], str, Dict[str, float]]: 循环信息, 回复文本, 循环计时器
"""
# 发送回复
with Timer("回复发送", cycle_timers):
reply_text, sent_messages = await self.response_handler.send_response(
response_set, loop_start_time, action_message
)
if sent_messages:
# 异步处理错别字修正
asyncio.create_task(self.response_handler.handle_typo_correction(sent_messages))
# 存储reply action信息
# 存储reply action信息
person_info_manager = get_person_info_manager()
# 获取 platform如果不存在则从 chat_stream 获取,如果还是 None 则使用默认值
@@ -66,6 +86,7 @@ class CycleProcessor:
if platform is None:
platform = getattr(self.context.chat_stream, "platform", "unknown")
# 获取用户信息并生成回复提示
person_id = person_info_manager.get_person_id(
platform,
action_message.get("user_id", ""),
@@ -73,6 +94,7 @@ class CycleProcessor:
person_name = await person_info_manager.get_value(person_id, "person_name")
action_prompt_display = f"你对{person_name}进行了回复:{reply_text}"
# 存储动作信息到数据库
await database_api.store_action_info(
chat_stream=self.context.chat_stream,
action_build_into_prompt=False,
@@ -106,7 +128,7 @@ class CycleProcessor:
interest_value: 兴趣值
Returns:
bool: 处理是否成功
str: 动作类型
功能说明:
- 开始新的思考循环并记录计时
@@ -122,6 +144,15 @@ class CycleProcessor:
# 当interest_value为0时概率接近0使用Focus模式
# 当interest_value很高时概率接近1使用Normal模式
def calculate_normal_mode_probability(interest_val: float) -> float:
"""
计算普通模式的概率
Args:
interest_val: 兴趣值
Returns:
float: 概率
"""
# 使用sigmoid函数调整参数使概率分布更合理
# 当interest_value = 0时概率约为0.1
# 当interest_value = 1时概率约为0.5
@@ -131,6 +162,7 @@ class CycleProcessor:
x0 = 1.0 # 控制曲线中心点
return 1.0 / (1.0 + math.exp(-k * (interest_val - x0)))
# 计算普通模式概率
normal_mode_probability = (
calculate_normal_mode_probability(interest_value)
* 0.5
@@ -149,9 +181,11 @@ class CycleProcessor:
f"{self.log_prefix} 基于兴趣值 {interest_value:.2f},概率 {normal_mode_probability:.2f}选择Focus planner模式"
)
# 开始新的思考循环
cycle_timers, thinking_id = self.cycle_tracker.start_cycle()
logger.info(f"{self.log_prefix} 开始第{self.context.cycle_counter}次思考")
# 发送正在输入状态
if ENABLE_S4U and self.context.chat_stream and self.context.chat_stream.user_info:
await send_typing(self.context.chat_stream.user_info.user_id)
@@ -176,12 +210,14 @@ class CycleProcessor:
from src.plugin_system.core.event_manager import event_manager
from src.plugin_system import EventType
# 触发规划前事件
result = await event_manager.trigger_event(
EventType.ON_PLAN, plugin_name="SYSTEM", stream_id=self.context.chat_stream
)
if result and not result.all_continue_process():
raise UserWarning(f"插件{result.get_summary().get('stopped_handlers', '')}于规划前中断了内容生成")
# 规划动作
with Timer("规划器", cycle_timers):
actions, _ = await self.action_planner.plan(
mode=mode,
@@ -227,6 +263,7 @@ class CycleProcessor:
"command": command,
}
else:
# 生成回复
try:
success, response_set, _ = await generator_api.generate_reply(
chat_stream=self.context.chat_stream,
@@ -245,6 +282,7 @@ class CycleProcessor:
logger.debug(f"{self.log_prefix} 并行执行:回复生成任务已被取消")
return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None}
# 发送并存储回复
loop_info, reply_text, cycle_timers_reply = await self._send_and_store_reply(
response_set,
loop_start_time,
@@ -323,13 +361,15 @@ class CycleProcessor:
}
reply_text = action_reply_text
# 停止正在输入状态
if ENABLE_S4U:
await stop_typing()
# 结束循环
self.context.chat_instance.cycle_tracker.end_cycle(loop_info, cycle_timers)
self.context.chat_instance.cycle_tracker.print_cycle_info(cycle_timers)
action_type = actions[0]["action_type"] if actions else "no_action"
action_type = actions["action_type"] if actions else "no_action"
return action_type
async def _handle_action(
@@ -357,6 +397,7 @@ class CycleProcessor:
if not self.context.chat_stream:
return False, "", ""
try:
# 创建动作处理器
action_handler = self.context.action_manager.create_action(
action_name=action,
action_data=action_data,
@@ -398,6 +439,7 @@ class CycleProcessor:
logger.error(f"{self.context.log_prefix} 回退方案也失败,无法创建任何动作处理器")
return False, "", ""
# 执行动作
success, reply_text = await action_handler.handle_action()
return success, reply_text, ""
except Exception as e:

View File

@@ -10,11 +10,15 @@ from .hfc_context import HfcContext
# 导入反注入系统
# 日志记录器
logger = get_logger("hfc")
anti_injector_logger = get_logger("anti_injector")
class ResponseHandler:
"""
响应处理器类,负责生成和发送机器人的回复。
"""
def __init__(self, context: HfcContext):
"""
初始化响应处理器
@@ -60,12 +64,15 @@ class ResponseHandler:
- 构建并返回完整的循环信息
- 用于上级方法的状态跟踪
"""
# 发送回复
reply_text, sent_messages = await self.send_response(response_set, loop_start_time, action_message)
if sent_messages:
# 异步处理错别字修正
asyncio.create_task(self.handle_typo_correction(sent_messages))
person_info_manager = get_person_info_manager()
# 获取平台信息
platform = "default"
if self.context.chat_stream:
platform = (
@@ -74,11 +81,13 @@ class ResponseHandler:
or self.context.chat_stream.platform
)
# 获取用户信息并生成回复提示
user_id = action_message.get("user_id", "")
person_id = person_info_manager.get_person_id(platform, user_id)
person_name = await person_info_manager.get_value(person_id, "person_name")
action_prompt_display = f"你对{person_name}进行了回复:{reply_text}"
# 存储动作信息到数据库
await database_api.store_action_info(
chat_stream=self.context.chat_stream,
action_build_into_prompt=False,
@@ -89,6 +98,7 @@ class ResponseHandler:
action_name="reply",
)
# 构建循环信息
loop_info: Dict[str, Any] = {
"loop_plan_info": {
"action_result": plan_result.get("action_result", {}),
@@ -123,10 +133,12 @@ class ResponseHandler:
- 正确处理元组格式的回复段
"""
current_time = time.time()
# 计算新消息数量
new_message_count = message_api.count_new_messages(
chat_id=self.context.stream_id, start_time=thinking_start_time, end_time=current_time
)
# 根据新消息数量决定是否需要引用回复
need_reply = new_message_count >= random.randint(2, 4)
reply_text = ""
@@ -137,6 +149,7 @@ class ResponseHandler:
for reply_seg in reply_set:
logger.debug(f"Processing reply_seg type: {type(reply_seg)}, content: {reply_seg}")
# 提取回复内容
if reply_seg["type"] == "typo":
data = reply_seg["typo"]
else:
@@ -144,10 +157,12 @@ class ResponseHandler:
reply_text += data
# 如果是主动思考且内容为“沉默”,则不发送
if is_proactive_thinking and data.strip() == "沉默":
logger.info(f"{self.context.log_prefix} 主动思考决定保持沉默,不发送消息")
continue
# 发送第一段回复
if not first_replied:
sent_message = await send_api.text_to_stream(
text=data,
@@ -158,6 +173,7 @@ class ResponseHandler:
)
first_replied = True
else:
# 发送后续回复
sent_message = await send_api.text_to_stream(
text=data,
stream_id=self.context.stream_id,
@@ -165,6 +181,7 @@ class ResponseHandler:
set_reply=False,
typing=True,
)
# 记录已发送的错别字消息
if sent_message and reply_seg["type"] == "typo":
sent_messages.append(
{
@@ -181,9 +198,12 @@ class ResponseHandler:
"""处理错别字修正"""
for msg in sent_messages:
if msg["type"] == "typo":
# 随机等待一段时间
await asyncio.sleep(random.uniform(2, 4))
# 撤回消息
recalled = await send_api.recall_message(str(msg["message_id"]), self.context.stream_id)
if recalled:
# 发送修正后的消息
await send_api.text_to_stream(
str(msg["correction"]), self.context.stream_id, reply_to_message=msg["original_message"]
)

View File

@@ -20,6 +20,7 @@ from src.plugin_system.base.component_types import ActionInfo
install(extra_lines=3)
# 日志记录器
logger = get_logger("generator_api")
@@ -113,6 +114,7 @@ async def generate_reply(
logger.debug("[GeneratorAPI] 开始生成回复")
# 向下兼容从action_data中获取reply_to和extra_info
if not reply_to and action_data:
reply_to = action_data.get("reply_to", "")
if not extra_info and action_data:
@@ -133,6 +135,7 @@ async def generate_reply(
return False, [], None
assert llm_response_dict is not None, "llm_response_dict不应为None" # 虽然说不会出现llm_response为空的情况
if content := llm_response_dict.get("content", ""):
# 处理为拟人化文本
reply_set = process_human_text(content, enable_splitter, enable_chinese_typo)
else:
reply_set = []
@@ -208,6 +211,7 @@ async def rewrite_reply(
)
reply_set = []
if content:
# 处理为拟人化文本
reply_set = process_human_text(content, enable_splitter, enable_chinese_typo)
if success:
@@ -238,6 +242,7 @@ def process_human_text(
if not isinstance(content, str):
raise ValueError("content 必须是字符串类型")
try:
# 处理LLM响应
processed_response = process_llm_response(content, enable_splitter, enable_chinese_typo)
reply_set = []
@@ -260,6 +265,18 @@ async def generate_response_custom(
request_type: str = "generator_api",
prompt: str = "",
) -> Optional[str]:
"""
使用自定义提示生成回复
Args:
chat_stream: 聊天流对象
chat_id: 聊天ID
request_type: 请求类型
prompt: 自定义提示
Returns:
Optional[str]: 生成的回复内容
"""
replyer = get_replyer(chat_stream, chat_id, request_type=request_type)
if not replyer:
logger.error("[GeneratorAPI] 无法获取回复器")

View File

@@ -43,6 +43,7 @@ from src.chat.message_receive.message import MessageSending, MessageRecv
from maim_message import Seg
from src.config.config import global_config
# 日志记录器
logger = get_logger("send_api")
# 适配器命令响应等待池
@@ -186,6 +187,7 @@ async def _send_to_target(
# 创建消息段
message_segment = Seg(type=message_type, data=content) # type: ignore
# 处理回复消息
if reply_to_message:
anchor_message = message_dict_to_message_recv(message_dict=reply_to_message)
if anchor_message and anchor_message.message_info and anchor_message.message_info.user_info: