Merge branch 'dev' of https://github.com/MaiM-with-u/MaiBot into PFC-test

pull/937/head
Bakadax 2025-05-16 14:45:01 +08:00
commit 1d4190c0bd
23 changed files with 1406 additions and 1373 deletions

View File

@ -1,18 +1,18 @@
# 麦麦MaiCore-MaiMBot (编辑中) # 麦麦MaiCore-MaiMBot (编辑中)
<br /> <br />
<div style="text-align: center"> <div align="center">
![Python Version](https://img.shields.io/badge/Python-3.10+-blue)
![License](https://img.shields.io/github/license/SengokuCola/MaiMBot?label=协议)
![Status](https://img.shields.io/badge/状态-开发中-yellow)
![Contributors](https://img.shields.io/github/contributors/MaiM-with-u/MaiBot.svg?style=flat&label=贡献者)
![forks](https://img.shields.io/github/forks/MaiM-with-u/MaiBot.svg?style=flat&label=分支数)
![stars](https://img.shields.io/github/stars/MaiM-with-u/MaiBot?style=flat&label=星标数)
![issues](https://img.shields.io/github/issues/MaiM-with-u/MaiBot)
![Python Version](https://img.shields.io/badge/Python-3.10+-blue)
![License](https://img.shields.io/github/license/SengokuCola/MaiMBot?label=协议)
![Status](https://img.shields.io/badge/状态-开发中-yellow)
![Contributors](https://img.shields.io/github/contributors/MaiM-with-u/MaiBot.svg?style=flat&label=贡献者)
![forks](https://img.shields.io/github/forks/MaiM-with-u/MaiBot.svg?style=flat&label=分支数)
![stars](https://img.shields.io/github/stars/MaiM-with-u/MaiBot?style=flat&label=星标数)
![issues](https://img.shields.io/github/issues/MaiM-with-u/MaiBot)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/DrSmoothl/MaiBot)
</div> </div>
<p style="text-align: center"> <p align="center">
<a href="https://github.com/MaiM-with-u/MaiBot/"> <a href="https://github.com/MaiM-with-u/MaiBot/">
<img src="depends-data/maimai.png" alt="Logo" style="width: 200px"> <img src="depends-data/maimai.png" alt="Logo" style="width: 200px">
</a> </a>
@ -21,8 +21,8 @@
画师略nd 画师略nd
</a> </a>
<h3 style="text-align: center">MaiBot(麦麦)</h3> <h3 align="center">MaiBot(麦麦)</h3>
<p style="text-align: center"> <p align="center">
一款专注于<strong> 群组聊天 </strong>的赛博网友 一款专注于<strong> 群组聊天 </strong>的赛博网友
<br /> <br />
<a href="https://docs.mai-mai.org"><strong>探索本项目的文档 »</strong></a> <a href="https://docs.mai-mai.org"><strong>探索本项目的文档 »</strong></a>

View File

@ -1,216 +0,0 @@
import os
import time
from typing import List, Dict, Any, Tuple
from src.chat.focus_chat.heartFC_Cycleinfo import CycleInfo
from src.common.logger_manager import get_logger
logger = get_logger("cycle_analyzer")
class CycleAnalyzer:
"""循环信息分析类提供查询和分析CycleInfo的工具"""
def __init__(self, base_dir: str = "log_debug"):
"""
初始化分析器
参数:
base_dir: 存储CycleInfo的基础目录默认为log_debug
"""
self.base_dir = base_dir
def list_streams(self) -> List[str]:
"""
获取所有聊天流ID列表
返回:
List[str]: 聊天流ID列表
"""
try:
if not os.path.exists(self.base_dir):
return []
return [d for d in os.listdir(self.base_dir) if os.path.isdir(os.path.join(self.base_dir, d))]
except Exception as e:
logger.error(f"获取聊天流列表时出错: {e}")
return []
def get_stream_cycle_count(self, stream_id: str) -> int:
"""
获取指定聊天流的循环数量
参数:
stream_id: 聊天流ID
返回:
int: 循环数量
"""
try:
files = CycleInfo.list_cycles(stream_id, self.base_dir)
return len(files)
except Exception as e:
logger.error(f"获取聊天流循环数量时出错: {e}")
return 0
def get_stream_cycles(self, stream_id: str, start: int = 0, limit: int = -1) -> List[str]:
"""
获取指定聊天流的循环文件列表
参数:
stream_id: 聊天流ID
start: 起始索引默认为0
limit: 返回的最大数量默认为-1全部
返回:
List[str]: 循环文件路径列表
"""
try:
files = CycleInfo.list_cycles(stream_id, self.base_dir)
if limit < 0:
return files[start:]
else:
return files[start : start + limit]
except Exception as e:
logger.error(f"获取聊天流循环文件列表时出错: {e}")
return []
def get_cycle_content(self, filepath: str) -> str:
"""
获取循环文件的内容
参数:
filepath: 文件路径
返回:
str: 文件内容
"""
try:
if not os.path.exists(filepath):
return f"文件不存在: {filepath}"
with open(filepath, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
logger.error(f"读取循环文件内容时出错: {e}")
return f"读取文件出错: {e}"
def analyze_stream_cycles(self, stream_id: str) -> Dict[str, Any]:
"""
分析指定聊天流的所有循环生成统计信息
参数:
stream_id: 聊天流ID
返回:
Dict[str, Any]: 统计信息
"""
try:
files = CycleInfo.list_cycles(stream_id, self.base_dir)
if not files:
return {"error": "没有找到循环记录"}
total_cycles = len(files)
action_counts = {"text_reply": 0, "emoji_reply": 0, "no_reply": 0, "unknown": 0}
total_duration = 0
tool_usage = {}
for filepath in files:
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
# 解析动作类型
for line in content.split("\n"):
if line.startswith("动作:"):
action = line[3:].strip()
action_counts[action] = action_counts.get(action, 0) + 1
# 解析耗时
elif line.startswith("耗时:"):
try:
duration = float(line[3:].strip().split("")[0])
total_duration += duration
except Exception as e:
logger.error(f"解析耗时时出错: {e}")
pass
# 解析工具使用
elif line.startswith("使用的工具:"):
tools = line[6:].strip().split(", ")
for tool in tools:
tool_usage[tool] = tool_usage.get(tool, 0) + 1
avg_duration = total_duration / total_cycles if total_cycles > 0 else 0
return {
"总循环数": total_cycles,
"动作统计": action_counts,
"平均耗时": f"{avg_duration:.2f}",
"总耗时": f"{total_duration:.2f}",
"工具使用次数": tool_usage,
}
except Exception as e:
logger.error(f"分析聊天流循环时出错: {e}")
return {"error": f"分析出错: {e}"}
def get_latest_cycles(self, count: int = 10) -> List[Tuple[str, str]]:
"""
获取所有聊天流中最新的几个循环
参数:
count: 获取的数量默认为10
返回:
List[Tuple[str, str]]: 聊天流ID和文件路径的元组列表
"""
try:
all_cycles = []
streams = self.list_streams()
for stream_id in streams:
files = CycleInfo.list_cycles(stream_id, self.base_dir)
for filepath in files:
try:
# 从文件名中提取时间戳
filename = os.path.basename(filepath)
timestamp_str = filename.split("_", 2)[2].split(".")[0]
timestamp = time.mktime(time.strptime(timestamp_str, "%Y%m%d_%H%M%S"))
all_cycles.append((timestamp, stream_id, filepath))
except Exception as e:
logger.error(f"从文件名中提取时间戳时出错: {e}")
continue
# 按时间戳排序取最新的count个
all_cycles.sort(reverse=True)
return [(item[1], item[2]) for item in all_cycles[:count]]
except Exception as e:
logger.error(f"获取最新循环时出错: {e}")
return []
# 使用示例
if __name__ == "__main__":
analyzer = CycleAnalyzer()
# 列出所有聊天流
streams = analyzer.list_streams()
print(f"找到 {len(streams)} 个聊天流: {streams}")
# 分析第一个聊天流的循环
if streams:
stream_id = streams[0]
stats = analyzer.analyze_stream_cycles(stream_id)
print(f"\n聊天流 {stream_id} 的统计信息:")
for key, value in stats.items():
print(f" {key}: {value}")
# 获取最新的循环
cycles = analyzer.get_stream_cycles(stream_id, limit=1)
if cycles:
print("\n最新循环内容:")
print(analyzer.get_cycle_content(cycles[0]))
# 获取所有聊天流中最新的3个循环
latest_cycles = analyzer.get_latest_cycles(3)
print(f"\n所有聊天流中最新的 {len(latest_cycles)} 个循环:")
for stream_id, filepath in latest_cycles:
print(f" 聊天流 {stream_id}: {os.path.basename(filepath)}")

View File

@ -248,7 +248,7 @@ class DefaultExpressor:
return None return None
mark_head = False mark_head = False
first_bot_msg: Optional[MessageSending] = None # first_bot_msg: Optional[MessageSending] = None
reply_message_ids = [] # 记录实际发送的消息ID reply_message_ids = [] # 记录实际发送的消息ID
sent_msg_list = [] sent_msg_list = []
@ -279,7 +279,7 @@ class DefaultExpressor:
try: try:
if not mark_head: if not mark_head:
mark_head = True mark_head = True
first_bot_msg = bot_message # 保存第一个成功发送的消息对象 # first_bot_msg = bot_message # 保存第一个成功发送的消息对象
typing = False typing = False
else: else:
typing = True typing = True

View File

@ -4,13 +4,13 @@ from typing import List, Dict, Optional, Any, Tuple
from src.common.logger_manager import get_logger from src.common.logger_manager import get_logger
from src.chat.models.utils_model import LLMRequest from src.chat.models.utils_model import LLMRequest
from src.config.config import global_config from src.config.config import global_config
from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_random, build_readable_messages, build_anonymous_messages from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_random, build_anonymous_messages
from src.chat.focus_chat.heartflow_prompt_builder import Prompt, global_prompt_manager from src.chat.focus_chat.heartflow_prompt_builder import Prompt, global_prompt_manager
import os import os
import json import json
MAX_EXPRESSION_COUNT = 300 MAX_EXPRESSION_COUNT = 100
logger = get_logger("expressor") logger = get_logger("expressor")
@ -19,7 +19,7 @@ def init_prompt() -> None:
learn_style_prompt = """ learn_style_prompt = """
{chat_str} {chat_str}
请从上面这段群聊中概括除了人名为"麦麦"之外的人的语言风格只考虑文字不要考虑表情包和图片 请从上面这段群聊中概括除了人名为"SELF"之外的人的语言风格只考虑文字不要考虑表情包和图片
不要涉及具体的人名只考虑语言风格 不要涉及具体的人名只考虑语言风格
语言风格包含特殊内容和情感 语言风格包含特殊内容和情感
思考有没有特殊的梗一并总结成语言风格 思考有没有特殊的梗一并总结成语言风格
@ -57,7 +57,7 @@ def init_prompt() -> None:
learn_grammar_prompt = """ learn_grammar_prompt = """
{chat_str} {chat_str}
请从上面这段群聊中概括除了人名为"麦麦"之外的人的语法和句法特点只考虑纯文字不要考虑表情包和图片 请从上面这段群聊中概括除了人名为"SELF"之外的人的语法和句法特点只考虑纯文字不要考虑表情包和图片
不要总结图片动画表情[图片][动画表情]不总结 表情符号 at @ 回复 [回复] 不要总结图片动画表情[图片][动画表情]不总结 表情符号 at @ 回复 [回复]
不要涉及具体的人名只考虑语法和句法特点, 不要涉及具体的人名只考虑语法和句法特点,
语法和句法特点要包括句子长短具体字数有何种语病如何拆分句子 语法和句法特点要包括句子长短具体字数有何种语病如何拆分句子
@ -65,9 +65,9 @@ def init_prompt() -> None:
"xxx"可以"xxx" "xxx"可以"xxx"
例如 例如
"表达观点较复杂"使用"省略主语"的句法 "表达观点较复杂"使用"省略主语(3-6个字)"的句法
"不用详细说明的一般表达"使用"非常简洁的句子"的句法 "不用详细说明的一般表达"使用"非常简洁的句子"的句法
"需要单纯简单的确认"使用"单字或几个字的肯定"的句法 "需要单纯简单的确认"使用"单字或几个字的肯定(1-2个字)"的句法
注意不要总结你自己的发言 注意不要总结你自己的发言
现在请你概括 现在请你概括
@ -122,11 +122,11 @@ class ExpressionLearner:
""" """
学习并存储表达方式分别学习语言风格和句法特点 学习并存储表达方式分别学习语言风格和句法特点
""" """
learnt_style: Optional[List[Tuple[str, str, str]]] = await self.learn_and_store(type="style", num=3) learnt_style: Optional[List[Tuple[str, str, str]]] = await self.learn_and_store(type="style", num=15)
if not learnt_style: if not learnt_style:
return [] return []
learnt_grammar: Optional[List[Tuple[str, str, str]]] = await self.learn_and_store(type="grammar", num=2) learnt_grammar: Optional[List[Tuple[str, str, str]]] = await self.learn_and_store(type="grammar", num=15)
if not learnt_grammar: if not learnt_grammar:
return [] return []
@ -233,7 +233,7 @@ class ExpressionLearner:
chat_str=random_msg_str, chat_str=random_msg_str,
) )
logger.info(f"学习{type_str}的prompt: {prompt}") # logger.info(f"学习{type_str}的prompt: {prompt}")
try: try:
response, _ = await self.express_learn_model.generate_response_async(prompt) response, _ = await self.express_learn_model.generate_response_async(prompt)
@ -291,7 +291,7 @@ class ExpressionLearner:
"personality_expression_prompt", "personality_expression_prompt",
personality=global_config.expression_style, personality=global_config.expression_style,
) )
logger.info(f"个性表达方式提取prompt: {prompt}") # logger.info(f"个性表达方式提取prompt: {prompt}")
try: try:
response, _ = await self.express_learn_model.generate_response_async(prompt) response, _ = await self.express_learn_model.generate_response_async(prompt)

View File

@ -1,6 +1,5 @@
import time import time
import os import os
import json
from typing import List, Optional, Dict, Any from typing import List, Optional, Dict, Any
@ -9,45 +8,16 @@ class CycleDetail:
def __init__(self, cycle_id: int): def __init__(self, cycle_id: int):
self.cycle_id = cycle_id self.cycle_id = cycle_id
self.thinking_id = ""
self.start_time = time.time() self.start_time = time.time()
self.end_time: Optional[float] = None self.end_time: Optional[float] = None
self.action_taken = False
self.action_type = "unknown"
self.reasoning = ""
self.timers: Dict[str, float] = {} self.timers: Dict[str, float] = {}
self.thinking_id = ""
self.replanned = False
# 添加响应信息相关字段 # 新字段
self.response_info: Dict[str, Any] = { self.loop_observation_info: Dict[str, Any] = {}
"response_text": [], # 回复的文本列表 self.loop_process_info: Dict[str, Any] = {}
"emoji_info": "", # 表情信息 self.loop_plan_info: Dict[str, Any] = {}
"anchor_message_id": "", # 锚点消息ID self.loop_action_info: Dict[str, Any] = {}
"reply_message_ids": [], # 回复消息ID列表
"sub_mind_thinking": "", # 子思维思考内容
"in_mind_reply": [], # 子思维思考内容
}
# 添加SubMind相关信息
self.submind_info: Dict[str, Any] = {
"prompt": "", # SubMind输入的prompt
"structured_info": "", # 结构化信息
"result": "", # SubMind的思考结果
}
# 添加ToolUse相关信息
self.tooluse_info: Dict[str, Any] = {
"prompt": "", # 工具使用的prompt
"tools_used": [], # 使用了哪些工具
"tool_results": [], # 工具获得的信息
}
# 添加Planner相关信息
self.planner_info: Dict[str, Any] = {
"prompt": "", # 规划器的prompt
"response": "", # 规划器的原始回复
"parsed_result": {}, # 解析后的结果
}
def to_dict(self) -> Dict[str, Any]: def to_dict(self) -> Dict[str, Any]:
"""将循环信息转换为字典格式""" """将循环信息转换为字典格式"""
@ -55,229 +25,28 @@ class CycleDetail:
"cycle_id": self.cycle_id, "cycle_id": self.cycle_id,
"start_time": self.start_time, "start_time": self.start_time,
"end_time": self.end_time, "end_time": self.end_time,
"action_taken": self.action_taken,
"action_type": self.action_type,
"reasoning": self.reasoning,
"timers": self.timers, "timers": self.timers,
"thinking_id": self.thinking_id, "thinking_id": self.thinking_id,
"response_info": self.response_info, "loop_observation_info": self.loop_observation_info,
"submind_info": self.submind_info, "loop_process_info": self.loop_process_info,
"tooluse_info": self.tooluse_info, "loop_plan_info": self.loop_plan_info,
"planner_info": self.planner_info, "loop_action_info": self.loop_action_info,
} }
def complete_cycle(self): def complete_cycle(self):
"""完成循环,记录结束时间""" """完成循环,记录结束时间"""
self.end_time = time.time() self.end_time = time.time()
def set_action_info(
self, action_type: str, reasoning: str, action_taken: bool, action_data: Optional[Dict[str, Any]] = None
):
"""设置动作信息"""
self.action_type = action_type
self.action_data = action_data
self.reasoning = reasoning
self.action_taken = action_taken
def set_thinking_id(self, thinking_id: str): def set_thinking_id(self, thinking_id: str):
"""设置思考消息ID""" """设置思考消息ID"""
self.thinking_id = thinking_id self.thinking_id = thinking_id
def set_response_info( def set_loop_info(self, loop_info: Dict[str, Any]):
self, """设置循环信息"""
response_text: Optional[List[str]] = None, self.loop_observation_info = loop_info["loop_observation_info"]
emoji_info: Optional[str] = None, self.loop_processor_info = loop_info["loop_processor_info"]
anchor_message_id: Optional[str] = None, self.loop_plan_info = loop_info["loop_plan_info"]
reply_message_ids: Optional[List[str]] = None, self.loop_action_info = loop_info["loop_action_info"]
sub_mind_thinking: Optional[str] = None,
):
"""设置响应信息"""
if response_text is not None:
self.response_info["response_text"] = response_text
if emoji_info is not None:
self.response_info["emoji_info"] = emoji_info
if anchor_message_id is not None:
self.response_info["anchor_message_id"] = anchor_message_id
if reply_message_ids is not None:
self.response_info["reply_message_ids"] = reply_message_ids
if sub_mind_thinking is not None:
self.response_info["sub_mind_thinking"] = sub_mind_thinking
def set_submind_info(
self,
prompt: Optional[str] = None,
structured_info: Optional[str] = None,
result: Optional[str] = None,
):
"""设置SubMind信息"""
if prompt is not None:
self.submind_info["prompt"] = prompt
if structured_info is not None:
self.submind_info["structured_info"] = structured_info
if result is not None:
self.submind_info["result"] = result
def set_tooluse_info(
self,
prompt: Optional[str] = None,
tools_used: Optional[List[str]] = None,
tool_results: Optional[List[Dict[str, Any]]] = None,
):
"""设置ToolUse信息"""
if prompt is not None:
self.tooluse_info["prompt"] = prompt
if tools_used is not None:
self.tooluse_info["tools_used"] = tools_used
if tool_results is not None:
self.tooluse_info["tool_results"] = tool_results
def set_planner_info(
self,
prompt: Optional[str] = None,
response: Optional[str] = None,
parsed_result: Optional[Dict[str, Any]] = None,
):
"""设置Planner信息"""
if prompt is not None:
self.planner_info["prompt"] = prompt
if response is not None:
self.planner_info["response"] = response
if parsed_result is not None:
self.planner_info["parsed_result"] = parsed_result
@staticmethod
def save_to_file(cycle_info: "CycleDetail", stream_id: str, base_dir: str = "log_debug") -> str:
"""
将CycleInfo保存到文件
参数:
cycle_info: CycleInfo对象
stream_id: 聊天流ID
base_dir: 基础目录默认为log_debug
返回:
str: 保存的文件路径
"""
try:
# 创建目录结构
stream_dir = os.path.join(base_dir, stream_id)
os.makedirs(stream_dir, exist_ok=True)
# 生成文件名和路径
timestamp = time.strftime("%Y%m%d_%H%M%S", time.localtime(cycle_info.start_time))
filename = f"cycle_{cycle_info.cycle_id}_{timestamp}.txt"
filepath = os.path.join(stream_dir, filename)
# 格式化输出成易读的格式
with open(filepath, "w", encoding="utf-8") as f:
# 写入基本信息
f.write(f"循环ID: {cycle_info.cycle_id}\n")
f.write(f"开始时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(cycle_info.start_time))}\n")
if cycle_info.end_time:
f.write(f"结束时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(cycle_info.end_time))}\n")
duration = cycle_info.end_time - cycle_info.start_time
f.write(f"耗时: {duration:.2f}\n")
f.write(f"动作: {cycle_info.action_type}\n")
f.write(f"原因: {cycle_info.reasoning}\n")
f.write(f"执行状态: {'已执行' if cycle_info.action_taken else '未执行'}\n")
f.write(f"思考ID: {cycle_info.thinking_id}\n")
f.write(f"是否为重新规划: {'' if cycle_info.replanned else ''}\n\n")
# 写入计时器信息
if cycle_info.timers:
f.write("== 计时器信息 ==\n")
for name, elapsed in cycle_info.timers.items():
formatted_time = f"{elapsed * 1000:.2f}毫秒" if elapsed < 1 else f"{elapsed:.2f}"
f.write(f"{name}: {formatted_time}\n")
f.write("\n")
# 写入响应信息
f.write("== 响应信息 ==\n")
f.write(f"锚点消息ID: {cycle_info.response_info['anchor_message_id']}\n")
if cycle_info.response_info["response_text"]:
f.write("回复文本:\n")
for i, text in enumerate(cycle_info.response_info["response_text"]):
f.write(f" [{i + 1}] {text}\n")
if cycle_info.response_info["emoji_info"]:
f.write(f"表情信息: {cycle_info.response_info['emoji_info']}\n")
if cycle_info.response_info["reply_message_ids"]:
f.write(f"回复消息ID: {', '.join(cycle_info.response_info['reply_message_ids'])}\n")
f.write("\n")
# 写入SubMind信息
f.write("== SubMind信息 ==\n")
f.write(f"结构化信息:\n{cycle_info.submind_info['structured_info']}\n\n")
f.write(f"思考结果:\n{cycle_info.submind_info['result']}\n\n")
f.write("SubMind Prompt:\n")
f.write(f"{cycle_info.submind_info['prompt']}\n\n")
# 写入ToolUse信息
f.write("== 工具使用信息 ==\n")
if cycle_info.tooluse_info["tools_used"]:
f.write(f"使用的工具: {', '.join(cycle_info.tooluse_info['tools_used'])}\n")
else:
f.write("未使用工具\n")
if cycle_info.tooluse_info["tool_results"]:
f.write("工具结果:\n")
for i, result in enumerate(cycle_info.tooluse_info["tool_results"]):
f.write(f" [{i + 1}] 类型: {result.get('type', '未知')}, 内容: {result.get('content', '')}\n")
f.write("\n")
f.write("工具执行 Prompt:\n")
f.write(f"{cycle_info.tooluse_info['prompt']}\n\n")
# 写入Planner信息
f.write("== Planner信息 ==\n")
f.write("Planner Prompt:\n")
f.write(f"{cycle_info.planner_info['prompt']}\n\n")
f.write("原始回复:\n")
f.write(f"{cycle_info.planner_info['response']}\n\n")
f.write("解析结果:\n")
f.write(f"{json.dumps(cycle_info.planner_info['parsed_result'], ensure_ascii=False, indent=2)}\n")
return filepath
except Exception as e:
print(f"保存CycleInfo到文件时出错: {e}")
return ""
@staticmethod
def load_from_file(filepath: str) -> Optional[Dict[str, Any]]:
"""
从文件加载CycleInfo信息只加载JSON格式的数据不解析文本格式
参数:
filepath: 文件路径
返回:
Optional[Dict[str, Any]]: 加载的CycleInfo数据失败则返回None
"""
try:
if not os.path.exists(filepath):
print(f"文件不存在: {filepath}")
return None
# 尝试从文件末尾读取JSON数据
with open(filepath, "r", encoding="utf-8") as f:
lines = f.readlines()
# 查找"解析结果:"后的JSON数据
for i, line in enumerate(lines):
if "解析结果:" in line and i + 1 < len(lines):
# 尝试解析后面的行
json_data = ""
for j in range(i + 1, len(lines)):
json_data += lines[j]
try:
return json.loads(json_data)
except json.JSONDecodeError:
continue
# 如果没有找到JSON数据则返回None
return None
except Exception as e:
print(f"从文件加载CycleInfo时出错: {e}")
return None
@staticmethod @staticmethod
def list_cycles(stream_id: str, base_dir: str = "log_debug") -> List[str]: def list_cycles(stream_id: str, base_dir: str = "log_debug") -> List[str]:

File diff suppressed because it is too large Load Diff

View File

@ -52,68 +52,11 @@ def init_prompt():
"info_from_tools", "info_from_tools",
) )
# Planner提示词 - 修改为要求 JSON 输出
Prompt(
"""你的名字是{bot_name},{prompt_personality}{chat_context_description}。需要基于以下信息决定如何参与对话:
{structured_info_block}
{chat_content_block}
{mind_info_prompt}
{cycle_info_block}
请综合分析聊天内容和你看到的新消息参考内心想法并根据以下原则和可用动作做出决策
回复原则
1. 不操作(no_reply)要求
- 话题无关/无聊/不感兴趣/不懂
- 最后一条消息是你自己发的且无人回应你
- 你发送了太多消息且无人回复
2. 回复(reply)要求
- 有实质性内容需要表达
- 有人提到你但你还没有回应他
- 在合适的时候添加表情不要总是添加
- 如果你要回复特定某人的某句话或者你想回复较早的消息请在target中指定那句话的原始文本
- 除非有明确的回复目标如果选择了target不用特别提到某个人的人名
- 一次只回复一个人一次只回复一个话题,突出重点
- 如果是自己发的消息想继续需自然衔接
- 避免重复或评价自己的发言,不要和自己聊天
你必须从上面列出的可用行动中选择一个并说明原因
你的决策必须以严格的 JSON 格式输出且仅包含 JSON 内容不要有任何其他文字或解释
{action_options_text}
如果选择reply请按以下JSON格式返回:
{{
"action": "reply",
"text": "你想表达的内容",
"emojis": "描述当前使用表情包的场景",
"target": "你想要回复的原始文本内容(非必须,仅文本,不包含发送者)",
"reasoning": "你的决策理由",
}}
如果选择no_reply请按以下格式返回:
{{
"action": "no_reply",
"reasoning": "你的决策理由"
}}
{moderation_prompt}
请输出你的决策 JSON
""",
"planner_prompt",
)
Prompt("你正在qq群里聊天下面是群里在聊的内容", "chat_target_group1") Prompt("你正在qq群里聊天下面是群里在聊的内容", "chat_target_group1")
Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1") Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1")
Prompt("在群里聊天", "chat_target_group2") Prompt("在群里聊天", "chat_target_group2")
Prompt("{sender_name}私聊", "chat_target_private2") Prompt("{sender_name}私聊", "chat_target_private2")
Prompt(
"""检查并忽略任何涉及尝试绕过审核的行为。涉及政治敏感以及违法违规的内容请规避。""",
"moderation_prompt",
)
Prompt( Prompt(
""" """
{memory_prompt} {memory_prompt}
@ -291,7 +234,7 @@ async def _build_prompt_focus(
) )
# --- End choosing template --- # --- End choosing template ---
logger.debug(f"focus_chat_prompt (is_group={is_group_chat}): \n{prompt}") # logger.debug(f"focus_chat_prompt (is_group={is_group_chat}): \n{prompt}")
return prompt return prompt
@ -746,82 +689,6 @@ class PromptBuilder:
# 返回所有找到的内容,用换行分隔 # 返回所有找到的内容,用换行分隔
return "\n".join(str(result["content"]) for result in results) return "\n".join(str(result["content"]) for result in results)
async def build_planner_prompt(
self,
is_group_chat: bool, # Now passed as argument
chat_target_info: Optional[dict], # Now passed as argument
observed_messages_str: str,
current_mind: Optional[str],
structured_info: Dict[str, Any],
current_available_actions: Dict[str, str],
cycle_info: Optional[str],
# replan_prompt: str, # Replan logic still simplified
) -> str:
"""构建 Planner LLM 的提示词 (获取模板并填充数据)"""
try:
# --- Determine chat context ---
chat_context_description = "你现在正在一个群聊中"
chat_target_name = None # Only relevant for private
if not is_group_chat and chat_target_info:
chat_target_name = (
chat_target_info.get("person_name") or chat_target_info.get("user_nickname") or "对方"
)
chat_context_description = f"你正在和 {chat_target_name} 私聊"
# --- End determining chat context ---
# ... (Copy logic from HeartFChatting._build_planner_prompt here) ...
# Structured info block
structured_info_block = ""
if structured_info:
structured_info_block = f"以下是一些额外的信息:\n{structured_info}\n"
# Chat content block
chat_content_block = ""
if observed_messages_str:
# Use triple quotes for multi-line string literal
chat_content_block = f"""观察到的最新聊天内容如下:
---
{observed_messages_str}
---"""
else:
chat_content_block = "当前没有观察到新的聊天内容。\\n"
# Current mind block
mind_info_prompt = ""
if current_mind:
mind_info_prompt = f"对聊天的规划:{current_mind}"
else:
mind_info_prompt = "你刚参与聊天"
individuality = Individuality.get_instance()
prompt_personality = individuality.get_prompt(x_person=2, level=2)
action_options_text = "当前你可以选择的行动有:\n"
action_keys = list(current_available_actions.keys())
for name in action_keys:
desc = current_available_actions[name]
action_options_text += f"- '{name}': {desc}\n"
planner_prompt_template = await global_prompt_manager.get_prompt_async("planner_prompt")
prompt = planner_prompt_template.format(
bot_name=global_config.BOT_NICKNAME,
prompt_personality=prompt_personality,
chat_context_description=chat_context_description,
structured_info_block=structured_info_block,
chat_content_block=chat_content_block,
mind_info_prompt=mind_info_prompt,
cycle_info_block=cycle_info,
action_options_text=action_options_text,
moderation_prompt=await global_prompt_manager.get_prompt_async("moderation_prompt"),
)
return prompt
except Exception as e:
logger.error(f"[PromptBuilder] 构建 Planner 提示词时出错: {e}")
logger.error(traceback.format_exc())
return "[构建 Planner Prompt 时出错]"
def weighted_sample_no_replacement(items, weights, k) -> list: def weighted_sample_no_replacement(items, weights, k) -> list:
""" """

View File

@ -14,15 +14,15 @@ class BaseProcessor(ABC):
支持处理InfoBase和Observation类型的输入 支持处理InfoBase和Observation类型的输入
""" """
log_prefix = "Base信息处理器"
@abstractmethod @abstractmethod
def __init__(self): def __init__(self):
"""初始化处理器""" """初始化处理器"""
pass
@abstractmethod @abstractmethod
async def process_info( async def process_info(
self, self,
infos: List[InfoBase],
observations: Optional[List[Observation]] = None, observations: Optional[List[Observation]] = None,
running_memorys: Optional[List[Dict]] = None, running_memorys: Optional[List[Dict]] = None,
**kwargs: Any, **kwargs: Any,

View File

@ -12,7 +12,7 @@ from typing import Dict
from src.chat.models.utils_model import LLMRequest from src.chat.models.utils_model import LLMRequest
from src.config.config import global_config from src.config.config import global_config
logger = get_logger("observation") logger = get_logger("processor")
class ChattingInfoProcessor(BaseProcessor): class ChattingInfoProcessor(BaseProcessor):
@ -21,12 +21,14 @@ class ChattingInfoProcessor(BaseProcessor):
用于处理Observation对象将其转换为ObsInfo对象 用于处理Observation对象将其转换为ObsInfo对象
""" """
log_prefix = "聊天信息处理"
def __init__(self): def __init__(self):
"""初始化观察处理器""" """初始化观察处理器"""
super().__init__()
self.llm_summary = LLMRequest( self.llm_summary = LLMRequest(
model=global_config.llm_observation, temperature=0.7, max_tokens=300, request_type="chat_observation" model=global_config.llm_observation, temperature=0.7, max_tokens=300, request_type="chat_observation"
) )
super().__init__()
async def process_info( async def process_info(
self, self,

View File

@ -24,17 +24,16 @@ from src.chat.focus_chat.info_processors.processor_utils import (
from typing import Dict from typing import Dict
from src.chat.focus_chat.info.info_base import InfoBase from src.chat.focus_chat.info.info_base import InfoBase
logger = get_logger("sub_heartflow") logger = get_logger("processor")
def init_prompt(): def init_prompt():
# --- Group Chat Prompt --- # --- Group Chat Prompt ---
group_prompt = """ group_prompt = """
你的名字是{bot_name}
{memory_str} {memory_str}
{extra_info} {extra_info}
{relation_prompt} {relation_prompt}
你的名字是{bot_name}
{mood_info}
{cycle_info_block} {cycle_info_block}
现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容 现在是{time_now}你正在上网和qq群里的网友们聊天以下是正在进行的聊天内容
{chat_observe_info} {chat_observe_info}
@ -74,8 +73,11 @@ def init_prompt():
class MindProcessor(BaseProcessor): class MindProcessor(BaseProcessor):
log_prefix = "聊天思考"
def __init__(self, subheartflow_id: str): def __init__(self, subheartflow_id: str):
super().__init__() super().__init__()
self.subheartflow_id = subheartflow_id self.subheartflow_id = subheartflow_id
self.llm_model = LLMRequest( self.llm_model = LLMRequest(
@ -228,7 +230,7 @@ class MindProcessor(BaseProcessor):
bot_name=individuality.name, bot_name=individuality.name,
time_now=time_now, time_now=time_now,
chat_observe_info=chat_observe_info, chat_observe_info=chat_observe_info,
mood_info="mood_info", # mood_info="mood_info",
hf_do_next=spark_prompt, hf_do_next=spark_prompt,
last_mind=previous_mind, last_mind=previous_mind,
cycle_info_block=hfcloop_observe_info, cycle_info_block=hfcloop_observe_info,

View File

@ -14,7 +14,7 @@ from src.chat.heart_flow.observation.observation import Observation
from src.chat.heart_flow.observation.working_observation import WorkingObservation from src.chat.heart_flow.observation.working_observation import WorkingObservation
from src.chat.focus_chat.info.structured_info import StructuredInfo from src.chat.focus_chat.info.structured_info import StructuredInfo
logger = get_logger("tool_use") logger = get_logger("processor")
def init_prompt(): def init_prompt():
@ -45,6 +45,8 @@ def init_prompt():
class ToolProcessor(BaseProcessor): class ToolProcessor(BaseProcessor):
log_prefix = "工具执行器"
def __init__(self, subheartflow_id: str): def __init__(self, subheartflow_id: str):
super().__init__() super().__init__()
self.subheartflow_id = subheartflow_id self.subheartflow_id = subheartflow_id

View File

@ -8,6 +8,7 @@ from src.chat.utils.prompt_builder import Prompt
from datetime import datetime from datetime import datetime
from src.chat.memory_system.Hippocampus import HippocampusManager from src.chat.memory_system.Hippocampus import HippocampusManager
from typing import List, Dict from typing import List, Dict
import difflib
logger = get_logger("memory_activator") logger = get_logger("memory_activator")
@ -82,7 +83,7 @@ class MemoryActivator:
text=obs_info_text, max_memory_num=3, max_memory_length=2, max_depth=3, fast_retrieval=True text=obs_info_text, max_memory_num=3, max_memory_length=2, max_depth=3, fast_retrieval=True
) )
logger.debug(f"获取到的记忆: {related_memory}") # logger.debug(f"获取到的记忆: {related_memory}")
# 激活时所有已有记忆的duration+1达到3则移除 # 激活时所有已有记忆的duration+1达到3则移除
for m in self.running_memory[:]: for m in self.running_memory[:]:
@ -91,14 +92,21 @@ class MemoryActivator:
if related_memory: if related_memory:
for topic, memory in related_memory: for topic, memory in related_memory:
# 检查是否已存在相同topic和content的记忆 # 检查是否已存在相同topic或相似内容相似度>=0.7)的记忆
exists = any(m["topic"] == topic and m["content"] == memory for m in self.running_memory) exists = any(
m["topic"] == topic or difflib.SequenceMatcher(None, m["content"], memory).ratio() >= 0.7
for m in self.running_memory
)
if not exists: if not exists:
self.running_memory.append( self.running_memory.append(
{"topic": topic, "content": memory, "timestamp": datetime.now().isoformat(), "duration": 1} {"topic": topic, "content": memory, "timestamp": datetime.now().isoformat(), "duration": 1}
) )
logger.debug(f"添加新记忆: {topic} - {memory}") logger.debug(f"添加新记忆: {topic} - {memory}")
# 限制同时加载的记忆条数最多保留最后3条
if len(self.running_memory) > 3:
self.running_memory = self.running_memory[-3:]
return self.running_memory return self.running_memory

View File

@ -0,0 +1,287 @@
from typing import Dict, List, Optional, Callable, Coroutine, Type, Any, Union
import os
import importlib
from src.chat.focus_chat.planners.actions.base_action import BaseAction, _ACTION_REGISTRY, _DEFAULT_ACTIONS
from src.chat.heart_flow.observation.observation import Observation
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
from src.chat.message_receive.chat_stream import ChatStream
from src.chat.focus_chat.heartFC_Cycleinfo import CycleDetail
from src.common.logger_manager import get_logger
# 导入动作类,确保装饰器被执行
from src.chat.focus_chat.planners.actions.reply_action import ReplyAction
from src.chat.focus_chat.planners.actions.no_reply_action import NoReplyAction
logger = get_logger("action_factory")
# 定义动作信息类型
ActionInfo = Dict[str, Any]
class ActionManager:
"""
动作管理器用于管理各种类型的动作
"""
def __init__(self):
"""初始化动作管理器"""
# 所有注册的动作集合
self._registered_actions: Dict[str, ActionInfo] = {}
# 当前正在使用的动作集合,默认加载默认动作
self._using_actions: Dict[str, ActionInfo] = {}
# 临时备份原始使用中的动作
self._original_actions_backup: Optional[Dict[str, ActionInfo]] = None
# 默认动作集,仅作为快照,用于恢复默认
self._default_actions: Dict[str, ActionInfo] = {}
# 加载所有已注册动作
self._load_registered_actions()
# 初始化时将默认动作加载到使用中的动作
self._using_actions = self._default_actions.copy()
# logger.info(f"当前可用动作: {list(self._using_actions.keys())}")
# for action_name, action_info in self._using_actions.items():
# logger.info(f"动作名称: {action_name}, 动作信息: {action_info}")
def _load_registered_actions(self) -> None:
"""
加载所有通过装饰器注册的动作
"""
try:
# 从_ACTION_REGISTRY获取所有已注册动作
for action_name, action_class in _ACTION_REGISTRY.items():
# 获取动作相关信息
action_description:str = getattr(action_class, "action_description", "")
action_parameters:dict[str:str] = getattr(action_class, "action_parameters", {})
action_require:list[str] = getattr(action_class, "action_require", [])
is_default:bool = getattr(action_class, "default", False)
if action_name and action_description:
# 创建动作信息字典
action_info = {
"description": action_description,
"parameters": action_parameters,
"require": action_require
}
# 注册2
print("注册2")
print(action_info)
# 添加到所有已注册的动作
self._registered_actions[action_name] = action_info
# 添加到默认动作(如果是默认动作)
if is_default:
self._default_actions[action_name] = action_info
logger.info(f"所有注册动作: {list(self._registered_actions.keys())}")
logger.info(f"默认动作: {list(self._default_actions.keys())}")
# for action_name, action_info in self._default_actions.items():
# logger.info(f"动作名称: {action_name}, 动作信息: {action_info}")
except Exception as e:
logger.error(f"加载已注册动作失败: {e}")
def create_action(
self,
action_name: str,
action_data: dict,
reasoning: str,
cycle_timers: dict,
thinking_id: str,
observations: List[Observation],
expressor: DefaultExpressor,
chat_stream: ChatStream,
current_cycle: CycleDetail,
log_prefix: str,
on_consecutive_no_reply_callback: Callable[[], Coroutine[None, None, None]],
total_no_reply_count: int = 0,
total_waiting_time: float = 0.0,
shutting_down: bool = False,
) -> Optional[BaseAction]:
"""
创建动作处理器实例
Args:
action_name: 动作名称
action_data: 动作数据
reasoning: 执行理由
cycle_timers: 计时器字典
thinking_id: 思考ID
observations: 观察列表
expressor: 表达器
chat_stream: 聊天流
current_cycle: 当前循环信息
log_prefix: 日志前缀
on_consecutive_no_reply_callback: 连续不回复回调
total_no_reply_count: 连续不回复计数
total_waiting_time: 累计等待时间
shutting_down: 是否正在关闭
Returns:
Optional[BaseAction]: 创建的动作处理器实例如果动作名称未注册则返回None
"""
# 检查动作是否在当前使用的动作集中
if action_name not in self._using_actions:
logger.warning(f"当前不可用的动作类型: {action_name}")
return None
handler_class = _ACTION_REGISTRY.get(action_name)
if not handler_class:
logger.warning(f"未注册的动作类型: {action_name}")
return None
try:
# 创建动作实例并传递所有必要参数
instance = handler_class(
action_name=action_name,
action_data=action_data,
reasoning=reasoning,
cycle_timers=cycle_timers,
thinking_id=thinking_id,
observations=observations,
on_consecutive_no_reply_callback=on_consecutive_no_reply_callback,
current_cycle=current_cycle,
log_prefix=log_prefix,
total_no_reply_count=total_no_reply_count,
total_waiting_time=total_waiting_time,
shutting_down=shutting_down,
expressor=expressor,
chat_stream=chat_stream,
)
return instance
except Exception as e:
logger.error(f"创建动作处理器实例失败: {e}")
return None
def get_registered_actions(self) -> Dict[str, ActionInfo]:
"""获取所有已注册的动作集"""
return self._registered_actions.copy()
def get_default_actions(self) -> Dict[str, ActionInfo]:
"""获取默认动作集"""
return self._default_actions.copy()
def get_using_actions(self) -> Dict[str, ActionInfo]:
"""获取当前正在使用的动作集"""
return self._using_actions.copy()
def add_action_to_using(self, action_name: str) -> bool:
"""
添加已注册的动作到当前使用的动作集
Args:
action_name: 动作名称
Returns:
bool: 添加是否成功
"""
if action_name not in self._registered_actions:
logger.warning(f"添加失败: 动作 {action_name} 未注册")
return False
if action_name in self._using_actions:
logger.info(f"动作 {action_name} 已经在使用中")
return True
self._using_actions[action_name] = self._registered_actions[action_name]
logger.info(f"添加动作 {action_name} 到使用集")
return True
def remove_action_from_using(self, action_name: str) -> bool:
"""
从当前使用的动作集中移除指定动作
Args:
action_name: 动作名称
Returns:
bool: 移除是否成功
"""
if action_name not in self._using_actions:
logger.warning(f"移除失败: 动作 {action_name} 不在当前使用的动作集中")
return False
del self._using_actions[action_name]
logger.info(f"已从使用集中移除动作 {action_name}")
return True
def add_action(self, action_name: str, description: str, parameters: Dict = None, require: List = None) -> bool:
"""
添加新的动作到注册集
Args:
action_name: 动作名称
description: 动作描述
parameters: 动作参数定义默认为空字典
require: 动作依赖项默认为空列表
Returns:
bool: 添加是否成功
"""
if action_name in self._registered_actions:
return False
if parameters is None:
parameters = {}
if require is None:
require = []
action_info = {
"description": description,
"parameters": parameters,
"require": require
}
self._registered_actions[action_name] = action_info
return True
def remove_action(self, action_name: str) -> bool:
"""从注册集移除指定动作"""
if action_name not in self._registered_actions:
return False
del self._registered_actions[action_name]
# 如果在使用集中也存在,一并移除
if action_name in self._using_actions:
del self._using_actions[action_name]
return True
def temporarily_remove_actions(self, actions_to_remove: List[str]) -> None:
"""临时移除使用集中的指定动作,备份原始使用集"""
if self._original_actions_backup is None:
self._original_actions_backup = self._using_actions.copy()
for name in actions_to_remove:
self._using_actions.pop(name, None)
def restore_actions(self) -> None:
"""恢复之前备份的原始使用集"""
if self._original_actions_backup is not None:
self._using_actions = self._original_actions_backup.copy()
self._original_actions_backup = None
def restore_default_actions(self) -> None:
"""恢复默认动作集到使用集"""
self._using_actions = self._default_actions.copy()
self._original_actions_backup = None
def get_action(self, action_name: str) -> Optional[Type[BaseAction]]:
"""
获取指定动作的处理器类
Args:
action_name: 动作名称
Returns:
Optional[Type[BaseAction]]: 动作处理器类如果不存在则返回None
"""
return _ACTION_REGISTRY.get(action_name)
# 创建全局实例
ActionFactory = ActionManager()

View File

@ -0,0 +1,84 @@
from abc import ABC, abstractmethod
from typing import Tuple, Dict, Type
from src.common.logger_manager import get_logger
logger = get_logger("base_action")
# 全局动作注册表
_ACTION_REGISTRY: Dict[str, Type["BaseAction"]] = {}
_DEFAULT_ACTIONS: Dict[str, str] = {}
def register_action(cls):
"""
动作注册装饰器
用法:
@register_action
class MyAction(BaseAction):
action_name = "my_action"
action_description = "我的动作"
...
"""
# 检查类是否有必要的属性
if not hasattr(cls, "action_name") or not hasattr(cls, "action_description"):
logger.error(f"动作类 {cls.__name__} 缺少必要的属性: action_name 或 action_description")
return cls
action_name = getattr(cls, "action_name")
action_description = getattr(cls, "action_description")
is_default = getattr(cls, "default", False)
if not action_name or not action_description:
logger.error(f"动作类 {cls.__name__} 的 action_name 或 action_description 为空")
return cls
# 将动作类注册到全局注册表
_ACTION_REGISTRY[action_name] = cls
# 如果是默认动作,添加到默认动作集
if is_default:
_DEFAULT_ACTIONS[action_name] = action_description
logger.info(f"已注册动作: {action_name} -> {cls.__name__},默认: {is_default}")
return cls
class BaseAction(ABC):
"""动作基类接口
所有具体的动作类都应该继承这个基类并实现handle_action方法
"""
def __init__(self, action_data: dict, reasoning: str, cycle_timers: dict, thinking_id: str):
"""初始化动作
Args:
action_name: 动作名称
action_data: 动作数据
reasoning: 执行该动作的理由
cycle_timers: 计时器字典
thinking_id: 思考ID
"""
#每个动作必须实现
self.action_name:str = "base_action"
self.action_description:str = "基础动作"
self.action_parameters:dict = {}
self.action_require:list[str] = []
self.default:bool = False
self.action_data = action_data
self.reasoning = reasoning
self.cycle_timers = cycle_timers
self.thinking_id = thinking_id
@abstractmethod
async def handle_action(self) -> Tuple[bool, str]:
"""处理动作的抽象方法,需要被子类实现
Returns:
Tuple[bool, str]: (是否执行成功, 回复文本)
"""
pass

View File

@ -0,0 +1,179 @@
import asyncio
import traceback
from src.common.logger_manager import get_logger
from src.chat.utils.timer_calculator import Timer
from src.chat.focus_chat.planners.actions.base_action import BaseAction, register_action
from typing import Tuple, List, Callable, Coroutine
from src.chat.heart_flow.observation.observation import Observation
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
from src.chat.focus_chat.heartFC_Cycleinfo import CycleDetail
from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp
logger = get_logger("action_taken")
# 常量定义
WAITING_TIME_THRESHOLD = 300 # 等待新消息时间阈值,单位秒
CONSECUTIVE_NO_REPLY_THRESHOLD = 3 # 连续不回复的阈值
@register_action
class NoReplyAction(BaseAction):
"""不回复动作处理类
处理决定不回复的动作
"""
action_name = "no_reply"
action_description = "不回复"
action_parameters = {}
action_require = [
"话题无关/无聊/不感兴趣/不懂",
"最后一条消息是你自己发的且无人回应你",
"你发送了太多消息,且无人回复"
]
default = True
def __init__(
self,
action_data: dict,
reasoning: str,
cycle_timers: dict,
thinking_id: str,
observations: List[Observation],
on_consecutive_no_reply_callback: Callable[[], Coroutine[None, None, None]],
current_cycle: CycleDetail,
log_prefix: str,
total_no_reply_count: int = 0,
total_waiting_time: float = 0.0,
shutting_down: bool = False,
**kwargs
):
"""初始化不回复动作处理器
Args:
action_name: 动作名称
action_data: 动作数据
reasoning: 执行该动作的理由
cycle_timers: 计时器字典
thinking_id: 思考ID
observations: 观察列表
on_consecutive_no_reply_callback: 连续不回复达到阈值时调用的回调函数
current_cycle: 当前循环信息
log_prefix: 日志前缀
total_no_reply_count: 连续不回复计数
total_waiting_time: 累计等待时间
shutting_down: 是否正在关闭
"""
super().__init__(action_data, reasoning, cycle_timers, thinking_id)
self.observations = observations
self.on_consecutive_no_reply_callback = on_consecutive_no_reply_callback
self._current_cycle = current_cycle
self.log_prefix = log_prefix
self.total_no_reply_count = total_no_reply_count
self.total_waiting_time = total_waiting_time
self._shutting_down = shutting_down
async def handle_action(self) -> Tuple[bool, str]:
"""
处理不回复的情况
工作流程
1. 等待新消息超时或关闭信号
2. 根据等待结果更新连续不回复计数
3. 如果达到阈值触发回调
Returns:
Tuple[bool, str]: (是否执行成功, 空字符串)
"""
logger.info(f"{self.log_prefix} 决定不回复: {self.reasoning}")
observation = self.observations[0] if self.observations else None
try:
with Timer("等待新消息", self.cycle_timers):
# 等待新消息、超时或关闭信号,并获取结果
await self._wait_for_new_message(observation, self.thinking_id, self.log_prefix)
# 从计时器获取实际等待时间
current_waiting = self.cycle_timers.get("等待新消息", 0.0)
if not self._shutting_down:
self.total_no_reply_count += 1
self.total_waiting_time += current_waiting # 累加等待时间
logger.debug(
f"{self.log_prefix} 连续不回复计数增加: {self.total_no_reply_count}/{CONSECUTIVE_NO_REPLY_THRESHOLD}, "
f"本次等待: {current_waiting:.2f}秒, 累计等待: {self.total_waiting_time:.2f}"
)
# 检查是否同时达到次数和时间阈值
time_threshold = 0.66 * WAITING_TIME_THRESHOLD * CONSECUTIVE_NO_REPLY_THRESHOLD
if (
self.total_no_reply_count >= CONSECUTIVE_NO_REPLY_THRESHOLD
and self.total_waiting_time >= time_threshold
):
logger.info(
f"{self.log_prefix} 连续不回复达到阈值 ({self.total_no_reply_count}次) "
f"且累计等待时间达到 {self.total_waiting_time:.2f}秒 (阈值 {time_threshold}秒)"
f"调用回调请求状态转换"
)
# 调用回调。注意:这里不重置计数器和时间,依赖回调函数成功改变状态来隐式重置上下文。
await self.on_consecutive_no_reply_callback()
elif self.total_no_reply_count >= CONSECUTIVE_NO_REPLY_THRESHOLD:
# 仅次数达到阈值,但时间未达到
logger.debug(
f"{self.log_prefix} 连续不回复次数达到阈值 ({self.total_no_reply_count}次) "
f"但累计等待时间 {self.total_waiting_time:.2f}秒 未达到时间阈值 ({time_threshold}秒),暂不调用回调"
)
# else: 次数和时间都未达到阈值,不做处理
return True, "" # 不回复动作没有回复文本
except asyncio.CancelledError:
logger.info(f"{self.log_prefix} 处理 'no_reply' 时等待被中断 (CancelledError)")
raise
except Exception as e: # 捕获调用管理器或其他地方可能发生的错误
logger.error(f"{self.log_prefix} 处理 'no_reply' 时发生错误: {e}")
logger.error(traceback.format_exc())
return False, ""
async def _wait_for_new_message(self, observation: ChattingObservation, thinking_id: str, log_prefix: str) -> bool:
"""
等待新消息 检测到关闭信号
参数:
observation: 观察实例
thinking_id: 思考ID
log_prefix: 日志前缀
返回:
bool: 是否检测到新消息 (如果因关闭信号退出则返回 False)
"""
wait_start_time = asyncio.get_event_loop().time()
while True:
# --- 在每次循环开始时检查关闭标志 ---
if self._shutting_down:
logger.info(f"{log_prefix} 等待新消息时检测到关闭信号,中断等待。")
return False # 表示因为关闭而退出
# -----------------------------------
thinking_id_timestamp = parse_thinking_id_to_timestamp(thinking_id)
# 检查新消息
if await observation.has_new_messages_since(thinking_id_timestamp):
logger.info(f"{log_prefix} 检测到新消息")
return True
# 检查超时 (放在检查新消息和关闭之后)
if asyncio.get_event_loop().time() - wait_start_time > WAITING_TIME_THRESHOLD:
logger.warning(f"{log_prefix} 等待新消息超时({WAITING_TIME_THRESHOLD}秒)")
return False
try:
# 短暂休眠,让其他任务有机会运行,并能更快响应取消或关闭
await asyncio.sleep(0.5) # 缩短休眠时间
except asyncio.CancelledError:
# 如果在休眠时被取消,再次检查关闭标志
# 如果是正常关闭,则不需要警告
if not self._shutting_down:
logger.warning(f"{log_prefix} _wait_for_new_message 的休眠被意外取消")
# 无论如何,重新抛出异常,让上层处理
raise

View File

@ -0,0 +1,142 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from src.common.logger_manager import get_logger
from src.chat.utils.timer_calculator import Timer
from src.chat.focus_chat.planners.actions.base_action import BaseAction, register_action
from typing import Tuple, List, Optional
from src.chat.heart_flow.observation.observation import Observation
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
from src.chat.message_receive.chat_stream import ChatStream
from src.chat.focus_chat.heartFC_Cycleinfo import CycleDetail
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
from src.chat.focus_chat.hfc_utils import create_empty_anchor_message
logger = get_logger("action_taken")
@register_action
class ReplyAction(BaseAction):
"""回复动作处理类
处理构建和发送消息回复的动作
"""
action_name:str = "reply"
action_description:str = "表达想法,可以只包含文本、表情或两者都有"
action_parameters:dict[str:str] = {
"text": "你想要表达的内容(可选)",
"emojis": "描述当前使用表情包的场景(可选)",
"target": "你想要回复的原始文本内容(非必须,仅文本,不包含发送者)(可选)",
}
action_require:list[str] = [
"有实质性内容需要表达",
"有人提到你,但你还没有回应他",
"在合适的时候添加表情(不要总是添加)",
"如果你要回复特定某人的某句话或者你想回复较早的消息请在target中指定那句话的原始文本",
"除非有明确的回复目标如果选择了target不用特别提到某个人的人名",
"一次只回复一个人,一次只回复一个话题,突出重点",
"如果是自己发的消息想继续,需自然衔接",
"避免重复或评价自己的发言,不要和自己聊天",
"注意:回复尽量简短一些。可以参考贴吧,知乎和微博的回复风格,回复不要浮夸,不要用夸张修辞,平淡一些。"
]
default = True
def __init__(
self,
action_name: str,
action_data: dict,
reasoning: str,
cycle_timers: dict,
thinking_id: str,
observations: List[Observation],
expressor: DefaultExpressor,
chat_stream: ChatStream,
current_cycle: CycleDetail,
log_prefix: str,
**kwargs
):
"""初始化回复动作处理器
Args:
action_name: 动作名称
action_data: 动作数据包含 message, emojis, target
reasoning: 执行该动作的理由
cycle_timers: 计时器字典
thinking_id: 思考ID
observations: 观察列表
expressor: 表达器
chat_stream: 聊天流
current_cycle: 当前循环信息
log_prefix: 日志前缀
"""
super().__init__(action_data, reasoning, cycle_timers, thinking_id)
self.observations = observations
self.expressor = expressor
self.chat_stream = chat_stream
self._current_cycle = current_cycle
self.log_prefix = log_prefix
async def handle_action(self) -> Tuple[bool, str]:
"""
处理回复动作
Returns:
Tuple[bool, str]: (是否执行成功, 回复文本)
"""
# 注意: 此处可能会使用不同的expressor实现根据任务类型切换不同的回复策略
return await self._handle_reply(
reasoning=self.reasoning,
reply_data=self.action_data,
cycle_timers=self.cycle_timers,
thinking_id=self.thinking_id
)
async def _handle_reply(
self, reasoning: str, reply_data: dict, cycle_timers: dict, thinking_id: str
) -> tuple[bool, str]:
"""
处理统一的回复动作 - 可包含文本和表情顺序任意
reply_data格式:
{
"text": "你好啊" # 文本内容列表(可选)
"target": "锚定消息", # 锚定消息的文本内容
"emojis": "微笑" # 表情关键词列表(可选)
}
"""
# 重置连续不回复计数器
self.total_no_reply_count = 0
self.total_waiting_time = 0.0
# 从聊天观察获取锚定消息
observations: ChattingObservation = self.observations[0]
anchor_message = observations.serch_message_by_text(reply_data["target"])
# 如果没有找到锚点消息,创建一个占位符
if not anchor_message:
logger.info(f"{self.log_prefix} 未找到锚点消息,创建占位符")
anchor_message = await create_empty_anchor_message(
self.chat_stream.platform, self.chat_stream.group_info, self.chat_stream
)
else:
anchor_message.update_chat_stream(self.chat_stream)
success, reply_set = await self.expressor.deal_reply(
cycle_timers=cycle_timers,
action_data=reply_data,
anchor_message=anchor_message,
reasoning=reasoning,
thinking_id=thinking_id,
)
reply_text = ""
for reply in reply_set:
type = reply[0]
data = reply[1]
if type == "text":
reply_text += data
elif type == "emoji":
reply_text += data
return success, reply_text

View File

@ -0,0 +1,286 @@
import json # <--- 确保导入 json
import traceback
from typing import List, Dict, Any, Optional
from rich.traceback import install
from src.chat.models.utils_model import LLMRequest
from src.config.config import global_config
from src.chat.focus_chat.heartflow_prompt_builder import prompt_builder
from src.chat.focus_chat.info.info_base import InfoBase
from src.chat.focus_chat.info.obs_info import ObsInfo
from src.chat.focus_chat.info.cycle_info import CycleInfo
from src.chat.focus_chat.info.mind_info import MindInfo
from src.chat.focus_chat.info.structured_info import StructuredInfo
from src.common.logger_manager import get_logger
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
from src.individuality.individuality import Individuality
from src.chat.focus_chat.planners.action_factory import ActionManager
from src.chat.focus_chat.planners.action_factory import ActionInfo
logger = get_logger("planner")
install(extra_lines=3)
def init_prompt():
Prompt(
"""你的名字是{bot_name},{prompt_personality}{chat_context_description}。需要基于以下信息决定如何参与对话:
{chat_content_block}
{mind_info_block}
{cycle_info_block}
请综合分析聊天内容和你看到的新消息参考聊天规划选择合适的action:
{action_options_text}
你必须从上面列出的可用action中选择一个并说明原因
你的决策必须以严格的 JSON 格式输出且仅包含 JSON 内容不要有任何其他文字或解释
请你以下面格式输出你选择的action
{{
"action": "action_name",
"reasoning": "你的决策理由",
"参数1": "参数1的值",
"参数2": "参数2的值",
"参数3": "参数3的值",
...
}}
请输出你的决策 JSON""",
"planner_prompt",)
Prompt(
"""
action_name: {action_name}
描述{action_description}
参数
{action_parameters}
动作要求
{action_require}
""",
"action_prompt",
)
class ActionPlanner:
def __init__(self, log_prefix: str, action_manager: ActionManager):
self.log_prefix = log_prefix
# LLM规划器配置
self.planner_llm = LLMRequest(
model=global_config.llm_plan,
max_tokens=1000,
request_type="action_planning", # 用于动作规划
)
self.action_manager = action_manager
async def plan(self, all_plan_info: List[InfoBase], cycle_timers: dict) -> Dict[str, Any]:
"""
规划器 (Planner): 使用LLM根据上下文决定做出什么动作
参数:
all_plan_info: 所有计划信息
cycle_timers: 计时器字典
"""
action = "no_reply" # 默认动作
reasoning = "规划器初始化默认"
try:
# 获取观察信息
for info in all_plan_info:
if isinstance(info, ObsInfo):
logger.debug(f"{self.log_prefix} 观察信息: {info}")
observed_messages = info.get_talking_message()
observed_messages_str = info.get_talking_message_str_truncate()
chat_type = info.get_chat_type()
if chat_type == "group":
is_group_chat = True
else:
is_group_chat = False
elif isinstance(info, MindInfo):
logger.debug(f"{self.log_prefix} 思维信息: {info}")
current_mind = info.get_current_mind()
elif isinstance(info, CycleInfo):
logger.debug(f"{self.log_prefix} 循环信息: {info}")
cycle_info = info.get_observe_info()
elif isinstance(info, StructuredInfo):
logger.debug(f"{self.log_prefix} 结构化信息: {info}")
structured_info = info.get_data()
current_available_actions = self.action_manager.get_using_actions()
# --- 构建提示词 (调用修改后的 PromptBuilder 方法) ---
prompt = await self.build_planner_prompt(
is_group_chat=is_group_chat, # <-- Pass HFC state
chat_target_info=None,
observed_messages_str=observed_messages_str, # <-- Pass local variable
current_mind=current_mind, # <-- Pass argument
# structured_info=structured_info, # <-- Pass SubMind info
current_available_actions=current_available_actions, # <-- Pass determined actions
cycle_info=cycle_info, # <-- Pass cycle info
)
# --- 调用 LLM (普通文本生成) ---
llm_content = None
try:
llm_content, _, _ = await self.planner_llm.generate_response(prompt=prompt)
logger.debug(f"{self.log_prefix}[Planner] LLM 原始 JSON 响应 (预期): {llm_content}")
except Exception as req_e:
logger.error(f"{self.log_prefix}[Planner] LLM 请求执行失败: {req_e}")
reasoning = f"LLM 请求失败,你的模型出现问题: {req_e}"
action = "no_reply"
if llm_content:
try:
# 尝试去除可能的 markdown 代码块标记
cleaned_content = (
llm_content.strip().removeprefix("```json").removeprefix("```").removesuffix("```").strip()
)
if not cleaned_content:
raise json.JSONDecodeError("Cleaned content is empty", cleaned_content, 0)
parsed_json = json.loads(cleaned_content)
# 提取决策,提供默认值
extracted_action = parsed_json.get("action", "no_reply")
extracted_reasoning = parsed_json.get("reasoning", "LLM未提供理由")
# 新的reply格式
if extracted_action == "reply":
action_data = {
"text": parsed_json.get("text", []),
"emojis": parsed_json.get("emojis", []),
"target": parsed_json.get("target", ""),
}
else:
action_data = {} # 其他动作可能不需要额外数据
if extracted_action not in current_available_actions:
logger.warning(
f"{self.log_prefix}LLM 返回了当前不可用或无效的动作: '{extracted_action}' (可用: {list(current_available_actions.keys())}),将强制使用 'no_reply'"
)
action = "no_reply"
reasoning = f"LLM 返回了当前不可用的动作 '{extracted_action}' (可用: {list(current_available_actions.keys())})。原始理由: {extracted_reasoning}"
else:
# 动作有效且可用
action = extracted_action
reasoning = extracted_reasoning
except Exception as json_e:
logger.warning(
f"{self.log_prefix}解析LLM响应JSON失败模型返回不标准: {json_e}. LLM原始输出: '{llm_content}'"
)
reasoning = f"解析LLM响应JSON失败: {json_e}. 将使用默认动作 'no_reply'."
action = "no_reply"
except Exception as outer_e:
logger.error(f"{self.log_prefix}Planner 处理过程中发生意外错误,规划失败,将执行 no_reply: {outer_e}")
traceback.print_exc()
action = "no_reply" # 发生未知错误,标记为 error 动作
reasoning = f"Planner 内部处理错误: {outer_e}"
logger.debug(
f"{self.log_prefix}规划器Prompt:\n{prompt}\n\n决策动作:{action},\n动作信息: '{action_data}'\n理由: {reasoning}"
)
# 恢复原始动作集
self.action_manager.restore_actions()
logger.debug(
f"{self.log_prefix}恢复了原始动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}"
)
action_result = {"action_type": action, "action_data": action_data, "reasoning": reasoning}
plan_result = {
"action_result": action_result,
"current_mind": current_mind,
"observed_messages": observed_messages,
}
# 返回结果字典
return plan_result
async def build_planner_prompt(
self,
is_group_chat: bool, # Now passed as argument
chat_target_info: Optional[dict], # Now passed as argument
observed_messages_str: str,
current_mind: Optional[str],
current_available_actions: Dict[str, ActionInfo],
cycle_info: Optional[str],
) -> str:
"""构建 Planner LLM 的提示词 (获取模板并填充数据)"""
try:
# --- Determine chat context ---
chat_context_description = "你现在正在一个群聊中"
chat_target_name = None # Only relevant for private
if not is_group_chat and chat_target_info:
chat_target_name = (
chat_target_info.get("person_name") or chat_target_info.get("user_nickname") or "对方"
)
chat_context_description = f"你正在和 {chat_target_name} 私聊"
chat_content_block = ""
if observed_messages_str:
chat_content_block = f"聊天记录:\n{observed_messages_str}"
else:
chat_content_block = "你还未开始聊天"
mind_info_block = ""
if current_mind:
mind_info_block = f"对聊天的规划:{current_mind}"
else:
mind_info_block = "你刚参与聊天"
individuality = Individuality.get_instance()
personality_block = individuality.get_prompt(x_person=2, level=2)
action_options_block = ""
for using_actions_name, using_actions_info in current_available_actions.items():
# print(using_actions_name)
# print(using_actions_info)
# print(using_actions_info["parameters"])
# print(using_actions_info["require"])
# print(using_actions_info["description"])
using_action_prompt = await global_prompt_manager.get_prompt_async("action_prompt")
param_text = ""
for param_name, param_description in using_actions_info["parameters"].items():
param_text += f"{param_name}: {param_description}\n"
require_text = ""
for require_item in using_actions_info["require"]:
require_text += f"- {require_item}\n"
using_action_prompt = using_action_prompt.format(
action_name=using_actions_name,
action_description=using_actions_info["description"],
action_parameters=param_text,
action_require=require_text,
)
action_options_block += using_action_prompt
planner_prompt_template = await global_prompt_manager.get_prompt_async("planner_prompt")
prompt = planner_prompt_template.format(
bot_name=global_config.BOT_NICKNAME,
prompt_personality=personality_block,
chat_context_description=chat_context_description,
chat_content_block=chat_content_block,
mind_info_block=mind_info_block,
cycle_info_block=cycle_info,
action_options_text=action_options_block,
)
return prompt
except Exception as e:
logger.error(f"构建 Planner 提示词时出错: {e}")
logger.error(traceback.format_exc())
return "构建 Planner Prompt 时出错"
init_prompt()

View File

@ -19,7 +19,7 @@ from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info
from src.chat.utils.prompt_builder import Prompt from src.chat.utils.prompt_builder import Prompt
logger = get_logger(__name__) logger = get_logger("observation")
Prompt( Prompt(

View File

@ -23,19 +23,16 @@ class HFCloopObservation:
def add_loop_info(self, loop_info: CycleDetail): def add_loop_info(self, loop_info: CycleDetail):
# logger.debug(f"添加循环信息111111111111111111111111111111111111: {loop_info}") # logger.debug(f"添加循环信息111111111111111111111111111111111111: {loop_info}")
# print(f"添加循环信息111111111111111111111111111111111111: {loop_info}") # print(f"添加循环信息111111111111111111111111111111111111: {loop_info}")
print(f"action_taken: {loop_info.action_taken}")
print(f"action_type: {loop_info.action_type}")
print(f"response_info: {loop_info.response_info}")
self.history_loop.append(loop_info) self.history_loop.append(loop_info)
async def observe(self): async def observe(self):
recent_active_cycles: List[CycleDetail] = [] recent_active_cycles: List[CycleDetail] = []
for cycle in reversed(self.history_loop): for cycle in reversed(self.history_loop):
# 只关心实际执行了动作的循环 # 只关心实际执行了动作的循环
if cycle.action_taken: action_taken = cycle.loop_action_info["action_taken"]
if action_taken:
recent_active_cycles.append(cycle) recent_active_cycles.append(cycle)
# 最多找最近的3个活动循环 if len(recent_active_cycles) == 5:
if len(recent_active_cycles) == 3:
break break
cycle_info_block = "" cycle_info_block = ""
@ -44,10 +41,10 @@ class HFCloopObservation:
# 检查这最近的活动循环中有多少是连续的文本回复 (从最近的开始看) # 检查这最近的活动循环中有多少是连续的文本回复 (从最近的开始看)
for cycle in recent_active_cycles: for cycle in recent_active_cycles:
if cycle.action_type == "reply": action_type = cycle.loop_plan_info["action_result"]["action_type"]
if action_type == "reply":
consecutive_text_replies += 1 consecutive_text_replies += 1
# 获取回复内容,如果不存在则返回'[空回复]' response_text = cycle.loop_plan_info["action_result"]["action_data"].get("text", "[空回复]")
response_text = cycle.response_info.get("response_text", "[空回复]")
responses_for_prompt.append(response_text) responses_for_prompt.append(response_text)
else: else:
break break
@ -70,7 +67,7 @@ class HFCloopObservation:
# 获取history_loop中最新添加的 # 获取history_loop中最新添加的
if self.history_loop: if self.history_loop:
last_loop = self.history_loop[-1] last_loop = self.history_loop[0]
start_time = last_loop.start_time start_time = last_loop.start_time
end_time = last_loop.end_time end_time = last_loop.end_time
if start_time is not None and end_time is not None: if start_time is not None and end_time is not None:

View File

@ -71,8 +71,9 @@ def get_raw_msg_by_timestamp_random(
# 随机选一条 # 随机选一条
msg = random.choice(all_msgs) msg = random.choice(all_msgs)
chat_id = msg["chat_id"] chat_id = msg["chat_id"]
timestamp_start = msg["time"]
# 用 chat_id 获取该聊天在指定时间戳范围内的消息 # 用 chat_id 获取该聊天在指定时间戳范围内的消息
return get_raw_msg_by_timestamp_with_chat(chat_id, timestamp_start, timestamp_end, limit, limit_mode) return get_raw_msg_by_timestamp_with_chat(chat_id, timestamp_start, timestamp_end, limit, "earliest")
def get_raw_msg_by_timestamp_with_users( def get_raw_msg_by_timestamp_with_users(
@ -331,7 +332,7 @@ async def _build_readable_messages_internal(
stripped_line = stripped_line[:-1] stripped_line = stripped_line[:-1]
# 如果内容被截断,结尾已经是 ...(内容太长),不再添加分号 # 如果内容被截断,结尾已经是 ...(内容太长),不再添加分号
if not stripped_line.endswith("(内容太长)"): if not stripped_line.endswith("(内容太长)"):
output_lines.append(f"{stripped_line};") output_lines.append(f"{stripped_line}")
else: else:
output_lines.append(stripped_line) # 直接添加截断后的内容 output_lines.append(stripped_line) # 直接添加截断后的内容
output_lines.append("\n") # 在每个消息块后添加换行,保持可读性 output_lines.append("\n") # 在每个消息块后添加换行,保持可读性
@ -416,15 +417,25 @@ async def build_readable_messages(
async def build_anonymous_messages(messages: List[Dict[str, Any]]) -> str: async def build_anonymous_messages(messages: List[Dict[str, Any]]) -> str:
""" """
构建匿名可读消息将不同人的名称转为唯一占位符ABC...bot自己用SELF 构建匿名可读消息将不同人的名称转为唯一占位符ABC...bot自己用SELF
处理 回复<aaa:bbb> @<aaa:bbb> 字段将bbb映射为匿名占位符
""" """
if not messages: if not messages:
return "" return ""
# 分配占位符
person_map = {} person_map = {}
current_char = ord('A') current_char = ord("A")
output_lines = [] output_lines = []
def get_anon_name(platform, user_id):
if user_id == global_config.BOT_QQ:
return "SELF"
person_id = person_info_manager.get_person_id(platform, user_id)
if person_id not in person_map:
nonlocal current_char
person_map[person_id] = chr(current_char)
current_char += 1
return person_map[person_id]
for msg in messages: for msg in messages:
user_info = msg.get("user_info", {}) user_info = msg.get("user_info", {})
platform = user_info.get("platform") platform = user_info.get("platform")
@ -435,25 +446,37 @@ async def build_anonymous_messages(messages: List[Dict[str, Any]]) -> str:
if not all([platform, user_id, timestamp is not None]): if not all([platform, user_id, timestamp is not None]):
continue continue
# 判断是否为bot anon_name = get_anon_name(platform, user_id)
if user_id == global_config.BOT_QQ:
anon_name = "SELF"
else:
person_id = person_info_manager.get_person_id(platform, user_id)
if person_id not in person_map:
person_map[person_id] = chr(current_char)
current_char += 1
anon_name = person_map[person_id]
# 格式化时间 # 处理 回复<aaa:bbb>
readable_time = translate_timestamp_to_human_readable(timestamp, mode="relative") reply_pattern = r"回复<([^:<>]+):([^:<>]+)>"
header = f"{readable_time}{anon_name}说:"
def reply_replacer(match):
# aaa = match.group(1)
bbb = match.group(2)
anon_reply = get_anon_name(platform, bbb)
return f"回复 {anon_reply}"
content = re.sub(reply_pattern, reply_replacer, content, count=1)
# 处理 @<aaa:bbb>
at_pattern = r"@<([^:<>]+):([^:<>]+)>"
def at_replacer(match):
# aaa = match.group(1)
bbb = match.group(2)
anon_at = get_anon_name(platform, bbb)
return f"@{anon_at}"
content = re.sub(at_pattern, at_replacer, content)
header = f"{anon_name}"
output_lines.append(header) output_lines.append(header)
stripped_line = content.strip() stripped_line = content.strip()
if stripped_line: if stripped_line:
if stripped_line.endswith(""): if stripped_line.endswith(""):
stripped_line = stripped_line[:-1] stripped_line = stripped_line[:-1]
output_lines.append(f"{stripped_line};") output_lines.append(f"{stripped_line}")
output_lines.append("\n") output_lines.append("\n")
formatted_string = "".join(output_lines).strip() formatted_string = "".join(output_lines).strip()

View File

@ -61,7 +61,7 @@ else:
"console_level": "INFO", "console_level": "INFO",
"file_level": "DEBUG", "file_level": "DEBUG",
# 格式配置 # 格式配置
"console_format": "<level>{time:MM-DD HH:mm}</level> | <cyan>{extra[module]}</cyan> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <cyan>{extra[module]}</cyan> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | {message}",
"log_dir": LOG_ROOT, "log_dir": LOG_ROOT,
"rotation": "00:00", "rotation": "00:00",
@ -82,7 +82,7 @@ MAIN_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-yellow>主程序</light-yellow> | <light-yellow>{message}</light-yellow>" "<level>{time:HH:mm:ss}</level> | <light-yellow>主程序</light-yellow> | <light-yellow>{message}</light-yellow>"
), ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 主程序 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 主程序 | {message}",
}, },
@ -101,7 +101,7 @@ PFC_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-green>PFC</light-green> | <light-green>{message}</light-green>" "<level>{time:HH:mm:ss}</level> | <light-green>PFC</light-green> | <light-green>{message}</light-green>"
), ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | PFC | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | PFC | {message}",
}, },
@ -119,7 +119,7 @@ MOOD_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <magenta>心情 | {message} </magenta>", "console_format": "<level>{time:HH:mm:ss}</level> | <magenta>心情 | {message} </magenta>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情 | {message}",
}, },
} }
@ -135,7 +135,7 @@ TOOL_USE_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 工具使用 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 工具使用 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <magenta>工具使用</magenta> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <magenta>工具使用</magenta> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 工具使用 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 工具使用 | {message}",
}, },
} }
@ -153,7 +153,7 @@ RELATION_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-magenta>关系</light-magenta> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-magenta>关系</light-magenta> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系 | {message}",
}, },
} }
@ -170,7 +170,7 @@ CONFIG_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 配置 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 配置 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-cyan>配置</light-cyan> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-cyan>配置</light-cyan> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 配置 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 配置 | {message}",
}, },
} }
@ -186,7 +186,7 @@ SENDER_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息发送 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息发送 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <green>消息发送</green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <green>消息发送</green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息发送 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息发送 | {message}",
}, },
} }
@ -203,7 +203,7 @@ HEARTFLOW_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-green>麦麦大脑袋</light-green> | <light-green>{message}</light-green>" "<level>{time:HH:mm:ss}</level> | <light-green>麦麦大脑袋</light-green> | <light-green>{message}</light-green>"
), # noqa: E501 ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦大脑袋 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦大脑袋 | {message}",
}, },
@ -220,7 +220,7 @@ SCHEDULE_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 在干嘛 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 在干嘛 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <cyan>在干嘛</cyan> | <cyan>{message}</cyan>", "console_format": "<level>{time:HH:mm:ss}</level> | <cyan>在干嘛</cyan> | <cyan>{message}</cyan>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 在干嘛 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 在干嘛 | {message}",
}, },
} }
@ -236,7 +236,7 @@ LLM_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦组织语言 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦组织语言 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>麦麦组织语言</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>麦麦组织语言</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦组织语言 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦组织语言 | {message}",
}, },
} }
@ -254,7 +254,7 @@ TOPIC_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 话题 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 话题 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-blue>主题</light-blue> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-blue>主题</light-blue> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 话题 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 话题 | {message}",
}, },
} }
@ -271,7 +271,7 @@ CHAT_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 见闻 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 见闻 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <green>见闻</green> | <green>{message}</green>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <green>见闻</green> | <green>{message}</green>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 见闻 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 见闻 | {message}",
}, },
} }
@ -287,7 +287,7 @@ REMOTE_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 远程 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 远程 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #00788A>远程| {message}</fg #00788A>", "console_format": "<level>{time:HH:mm:ss}</level> | <fg #00788A>远程| {message}</fg #00788A>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 远程 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 远程 | {message}",
}, },
} }
@ -303,7 +303,7 @@ SUB_HEARTFLOW_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦小脑袋 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦小脑袋 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #3399FF>麦麦水群 | {message}</fg #3399FF>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <fg #3399FF>麦麦水群 | {message}</fg #3399FF>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦水群 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦水群 | {message}",
}, },
} }
@ -319,7 +319,7 @@ INTEREST_CHAT_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 兴趣 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 兴趣 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #55DDFF>兴趣 | {message}</fg #55DDFF>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <fg #55DDFF>兴趣 | {message}</fg #55DDFF>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 兴趣 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 兴趣 | {message}",
}, },
} }
@ -336,7 +336,7 @@ SUB_HEARTFLOW_MIND_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦小脑袋 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦小脑袋 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #66CCFF>麦麦小脑袋 | {message}</fg #66CCFF>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <fg #66CCFF>麦麦小脑袋 | {message}</fg #66CCFF>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦小脑袋 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦小脑袋 | {message}",
}, },
} }
@ -352,7 +352,7 @@ SUBHEARTFLOW_MANAGER_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦水群[管理] | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦水群[管理] | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #005BA2>麦麦水群[管理] | {message}</fg #005BA2>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <fg #005BA2>麦麦水群[管理] | {message}</fg #005BA2>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦水群[管理] | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦水群[管理] | {message}",
}, },
} }
@ -369,7 +369,7 @@ BASE_TOOL_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-blue>工具使用</light-blue> | <light-blue>{message}</light-blue>" "<level>{time:HH:mm:ss}</level> | <light-blue>工具使用</light-blue> | <light-blue>{message}</light-blue>"
), # noqa: E501 ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 工具使用 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 工具使用 | {message}",
}, },
@ -387,7 +387,7 @@ CHAT_STREAM_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-blue>聊天流</light-blue> | <light-blue>{message}</light-blue>" "<level>{time:HH:mm:ss}</level> | <light-blue>聊天流</light-blue> | <light-blue>{message}</light-blue>"
), ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天流 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天流 | {message}",
}, },
@ -405,7 +405,7 @@ CHAT_MESSAGE_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-blue>聊天消息</light-blue> | <light-blue>{message}</light-blue>" "<level>{time:HH:mm:ss}</level> | <light-blue>聊天消息</light-blue> | <light-blue>{message}</light-blue>"
), # noqa: E501 ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天消息 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天消息 | {message}",
}, },
@ -423,7 +423,7 @@ PERSON_INFO_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-blue>人物信息</light-blue> | <light-blue>{message}</light-blue>" "<level>{time:HH:mm:ss}</level> | <light-blue>人物信息</light-blue> | <light-blue>{message}</light-blue>"
), # noqa: E501 ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 人物信息 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 人物信息 | {message}",
}, },
@ -441,7 +441,7 @@ BACKGROUND_TASKS_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-blue>后台任务</light-blue> | <light-blue>{message}</light-blue>" "<level>{time:HH:mm:ss}</level> | <light-blue>后台任务</light-blue> | <light-blue>{message}</light-blue>"
), # noqa: E501 ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 后台任务 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 后台任务 | {message}",
}, },
@ -458,7 +458,7 @@ WILLING_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 意愿 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 意愿 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-blue>意愿 | {message} </light-blue>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <light-blue>意愿 | {message} </light-blue>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 意愿 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 意愿 | {message}",
}, },
} }
@ -474,7 +474,7 @@ PFC_ACTION_PLANNER_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | PFC私聊规划 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | PFC私聊规划 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-blue>PFC私聊规划 | {message} </light-blue>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <light-blue>PFC私聊规划 | {message} </light-blue>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | PFC私聊规划 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | PFC私聊规划 | {message}",
}, },
} }
@ -491,7 +491,7 @@ EMOJI_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 表情包 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 表情包 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #FFD700>表情包 | {message} </fg #FFD700>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <fg #FFD700>表情包 | {message} </fg #FFD700>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 表情包 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 表情包 | {message}",
}, },
} }
@ -507,7 +507,7 @@ MAI_STATE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦状态 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦状态 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <fg #66CCFF>麦麦状态 | {message} </fg #66CCFF>", # noqa: E501 "console_format": "<level>{time:HH:mm:ss}</level> | <fg #66CCFF>麦麦状态 | {message} </fg #66CCFF>", # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦状态 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 麦麦状态 | {message}",
}, },
} }
@ -526,7 +526,7 @@ MEMORY_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <fg #7CFFE6>海马体</fg #7CFFE6> | <fg #7CFFE6>{message}</fg #7CFFE6>" "<level>{time:HH:mm:ss}</level> | <fg #7CFFE6>海马体</fg #7CFFE6> | <fg #7CFFE6>{message}</fg #7CFFE6>"
), ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 海马体 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 海马体 | {message}",
}, },
@ -546,29 +546,29 @@ LPMM_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <fg #37FFB4>LPMM</fg #37FFB4> | <fg #37FFB4>{message}</fg #37FFB4>" "<level>{time:HH:mm:ss}</level> | <fg #37FFB4>LPMM</fg #37FFB4> | <fg #37FFB4>{message}</fg #37FFB4>"
), ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | LPMM | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | LPMM | {message}",
}, },
} }
OBSERVATION_STYLE_CONFIG = { # OBSERVATION_STYLE_CONFIG = {
"advanced": { # "advanced": {
"console_format": ( # "console_format": (
"<white>{time:YYYY-MM-DD HH:mm:ss}</white> | " # "<white>{time:YYYY-MM-DD HH:mm:ss}</white> | "
"<level>{level: <8}</level> | " # "<level>{level: <8}</level> | "
"<light-yellow>聊天观察</light-yellow> | " # "<light-yellow>聊天观察</light-yellow> | "
"<level>{message}</level>" # "<level>{message}</level>"
), # ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天观察 | {message}", # "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天观察 | {message}",
}, # },
"simple": { # "simple": {
"console_format": ( # "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-yellow>聊天观察</light-yellow> | <light-yellow>{message}</light-yellow>" # "<level>{time:HH:mm:ss}</level> | <light-yellow>聊天观察</light-yellow> | <light-yellow>{message}</light-yellow>"
), # noqa: E501 # ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天观察 | {message}", # "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天观察 | {message}",
}, # },
} # }
CHAT_IMAGE_STYLE_CONFIG = { CHAT_IMAGE_STYLE_CONFIG = {
"advanced": { "advanced": {
@ -582,7 +582,7 @@ CHAT_IMAGE_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <light-yellow>聊天图片</light-yellow> | <light-yellow>{message}</light-yellow>" "<level>{time:HH:mm:ss}</level> | <light-yellow>聊天图片</light-yellow> | <light-yellow>{message}</light-yellow>"
), # noqa: E501 ), # noqa: E501
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天图片 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 聊天图片 | {message}",
}, },
@ -600,11 +600,55 @@ HFC_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 专注聊天 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 专注聊天 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>专注聊天 | {message}</light-green>", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>专注聊天 | {message}</light-green>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 专注聊天 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 专注聊天 | {message}",
}, },
} }
OBSERVATION_STYLE_CONFIG = {
"advanced": {
"console_format": "<level>{time:HH:mm:ss}</level> | <light-yellow>观察</light-yellow> | <light-yellow>{message}</light-yellow>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 观察 | {message}",
},
"simple": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #66CCFF>观察</fg #66CCFF> | <fg #66CCFF>{message}</fg #66CCFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 观察 | {message}",
},
}
PROCESSOR_STYLE_CONFIG = {
"advanced": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #54DDFF>处理器</fg #54DDFF> | <fg #54DDFF>{message}</fg #54DDFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 处理器 | {message}",
},
"simple": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #54DDFF>处理器</fg #54DDFF> | <fg #54DDFF>{message}</fg #54DDFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 处理器 | {message}",
},
}
PLANNER_STYLE_CONFIG = {
"advanced": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #36DEFF>规划器</fg #36DEFF> | <fg #36DEFF>{message}</fg #36DEFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 规划器 | {message}",
},
"simple": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #36DEFF>规划器</fg #36DEFF> | <fg #36DEFF>{message}</fg #36DEFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 规划器 | {message}",
},
}
ACTION_TAKEN_STYLE_CONFIG = {
"advanced": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #22DAFF>动作</fg #22DAFF> | <fg #22DAFF>{message}</fg #22DAFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 动作 | {message}",
},
"simple": {
"console_format": "<level>{time:HH:mm:ss}</level> | <fg #22DAFF>动作</fg #22DAFF> | <fg #22DAFF>{message}</fg #22DAFF>",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 动作 | {message}",
},
}
CONFIRM_STYLE_CONFIG = { CONFIRM_STYLE_CONFIG = {
"console_format": "<RED>{message}</RED>", # noqa: E501 "console_format": "<RED>{message}</RED>", # noqa: E501
@ -624,7 +668,7 @@ TIANYI_STYLE_CONFIG = {
}, },
"simple": { "simple": {
"console_format": ( "console_format": (
"<level>{time:MM-DD HH:mm}</level> | <fg #66CCFF>天依</fg #66CCFF> | <fg #66CCFF>{message}</fg #66CCFF>" "<level>{time:HH:mm:ss}</level> | <fg #66CCFF>天依</fg #66CCFF> | <fg #66CCFF>{message}</fg #66CCFF>"
), ),
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 天依 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 天依 | {message}",
}, },
@ -642,7 +686,7 @@ MODEL_UTILS_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 模型 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 模型 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>模型</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>模型</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 模型 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 模型 | {message}",
}, },
} }
@ -658,7 +702,7 @@ MESSAGE_BUFFER_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息缓存 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息缓存 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>消息缓存</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>消息缓存</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息缓存 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 消息缓存 | {message}",
}, },
} }
@ -674,7 +718,7 @@ PROMPT_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 提示词构建 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 提示词构建 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>提示词构建</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>提示词构建</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 提示词构建 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 提示词构建 | {message}",
}, },
} }
@ -690,7 +734,7 @@ CHANGE_MOOD_TOOL_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情工具 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情工具 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>心情工具</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>心情工具</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情工具 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 心情工具 | {message}",
}, },
} }
@ -706,7 +750,7 @@ CHANGE_RELATIONSHIP_TOOL_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系工具 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系工具 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>关系工具</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>关系工具</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系工具 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 关系工具 | {message}",
}, },
} }
@ -722,7 +766,7 @@ GET_KNOWLEDGE_TOOL_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取知识 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取知识 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>获取知识</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>获取知识</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取知识 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取知识 | {message}",
}, },
} }
@ -738,7 +782,7 @@ GET_TIME_DATE_TOOL_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取时间日期 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取时间日期 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>获取时间日期</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>获取时间日期</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取时间日期 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 获取时间日期 | {message}",
}, },
} }
@ -754,7 +798,7 @@ LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | LPMM获取知识 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | LPMM获取知识 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>LPMM获取知识</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>LPMM获取知识</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | LPMM获取知识 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | LPMM获取知识 | {message}",
}, },
} }
@ -770,7 +814,7 @@ INIT_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 初始化 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 初始化 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>初始化</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>初始化</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 初始化 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | 初始化 | {message}",
}, },
} }
@ -786,7 +830,7 @@ API_SERVER_STYLE_CONFIG = {
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | API服务 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | API服务 | {message}",
}, },
"simple": { "simple": {
"console_format": "<level>{time:MM-DD HH:mm}</level> | <light-green>API服务</light-green> | {message}", "console_format": "<level>{time:HH:mm:ss}</level> | <light-green>API服务</light-green> | {message}",
"file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | API服务 | {message}", "file_format": "{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {extra[module]: <15} | API服务 | {message}",
}, },
} }
@ -830,6 +874,12 @@ TOOL_USE_STYLE_CONFIG = TOOL_USE_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else TO
PFC_STYLE_CONFIG = PFC_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PFC_STYLE_CONFIG["advanced"] PFC_STYLE_CONFIG = PFC_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PFC_STYLE_CONFIG["advanced"]
LPMM_STYLE_CONFIG = LPMM_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else LPMM_STYLE_CONFIG["advanced"] LPMM_STYLE_CONFIG = LPMM_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else LPMM_STYLE_CONFIG["advanced"]
HFC_STYLE_CONFIG = HFC_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else HFC_STYLE_CONFIG["advanced"] HFC_STYLE_CONFIG = HFC_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else HFC_STYLE_CONFIG["advanced"]
ACTION_TAKEN_STYLE_CONFIG = (
ACTION_TAKEN_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else ACTION_TAKEN_STYLE_CONFIG["advanced"]
)
OBSERVATION_STYLE_CONFIG = OBSERVATION_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else OBSERVATION_STYLE_CONFIG["advanced"]
PLANNER_STYLE_CONFIG = PLANNER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PLANNER_STYLE_CONFIG["advanced"]
PROCESSOR_STYLE_CONFIG = PROCESSOR_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PROCESSOR_STYLE_CONFIG["advanced"]
TIANYI_STYLE_CONFIG = TIANYI_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else TIANYI_STYLE_CONFIG["advanced"] TIANYI_STYLE_CONFIG = TIANYI_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else TIANYI_STYLE_CONFIG["advanced"]
MODEL_UTILS_STYLE_CONFIG = MODEL_UTILS_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MODEL_UTILS_STYLE_CONFIG["advanced"] MODEL_UTILS_STYLE_CONFIG = MODEL_UTILS_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MODEL_UTILS_STYLE_CONFIG["advanced"]
PROMPT_STYLE_CONFIG = PROMPT_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PROMPT_STYLE_CONFIG["advanced"] PROMPT_STYLE_CONFIG = PROMPT_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else PROMPT_STYLE_CONFIG["advanced"]
@ -852,7 +902,7 @@ LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG = (
if SIMPLE_OUTPUT if SIMPLE_OUTPUT
else LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG["advanced"] else LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG["advanced"]
) )
OBSERVATION_STYLE_CONFIG = OBSERVATION_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else OBSERVATION_STYLE_CONFIG["advanced"] # OBSERVATION_STYLE_CONFIG = OBSERVATION_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else OBSERVATION_STYLE_CONFIG["advanced"]
MESSAGE_BUFFER_STYLE_CONFIG = ( MESSAGE_BUFFER_STYLE_CONFIG = (
MESSAGE_BUFFER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MESSAGE_BUFFER_STYLE_CONFIG["advanced"] MESSAGE_BUFFER_STYLE_CONFIG["simple"] if SIMPLE_OUTPUT else MESSAGE_BUFFER_STYLE_CONFIG["advanced"]
) )

View File

@ -23,6 +23,10 @@ from src.common.logger import (
MAI_STATE_CONFIG, MAI_STATE_CONFIG,
LPMM_STYLE_CONFIG, LPMM_STYLE_CONFIG,
HFC_STYLE_CONFIG, HFC_STYLE_CONFIG,
OBSERVATION_STYLE_CONFIG,
PLANNER_STYLE_CONFIG,
PROCESSOR_STYLE_CONFIG,
ACTION_TAKEN_STYLE_CONFIG,
TIANYI_STYLE_CONFIG, TIANYI_STYLE_CONFIG,
REMOTE_STYLE_CONFIG, REMOTE_STYLE_CONFIG,
TOPIC_STYLE_CONFIG, TOPIC_STYLE_CONFIG,
@ -35,7 +39,6 @@ from src.common.logger import (
GET_KNOWLEDGE_TOOL_STYLE_CONFIG, GET_KNOWLEDGE_TOOL_STYLE_CONFIG,
GET_TIME_DATE_TOOL_STYLE_CONFIG, GET_TIME_DATE_TOOL_STYLE_CONFIG,
LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG, LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG,
OBSERVATION_STYLE_CONFIG,
MESSAGE_BUFFER_STYLE_CONFIG, MESSAGE_BUFFER_STYLE_CONFIG,
CHAT_MESSAGE_STYLE_CONFIG, CHAT_MESSAGE_STYLE_CONFIG,
CHAT_IMAGE_STYLE_CONFIG, CHAT_IMAGE_STYLE_CONFIG,
@ -69,6 +72,10 @@ MODULE_LOGGER_CONFIGS = {
"mai_state": MAI_STATE_CONFIG, # 麦麦状态 "mai_state": MAI_STATE_CONFIG, # 麦麦状态
"lpmm": LPMM_STYLE_CONFIG, # LPMM "lpmm": LPMM_STYLE_CONFIG, # LPMM
"hfc": HFC_STYLE_CONFIG, # HFC "hfc": HFC_STYLE_CONFIG, # HFC
"observation": OBSERVATION_STYLE_CONFIG, # 聊天观察
"planner": PLANNER_STYLE_CONFIG, # 规划器
"processor": PROCESSOR_STYLE_CONFIG, # 处理器
"action_taken": ACTION_TAKEN_STYLE_CONFIG, # 动作
"tianyi": TIANYI_STYLE_CONFIG, # 天依 "tianyi": TIANYI_STYLE_CONFIG, # 天依
"remote": REMOTE_STYLE_CONFIG, # 远程 "remote": REMOTE_STYLE_CONFIG, # 远程
"topic": TOPIC_STYLE_CONFIG, # 话题 "topic": TOPIC_STYLE_CONFIG, # 话题
@ -81,7 +88,6 @@ MODULE_LOGGER_CONFIGS = {
"get_knowledge_tool": GET_KNOWLEDGE_TOOL_STYLE_CONFIG, # 获取知识工具 "get_knowledge_tool": GET_KNOWLEDGE_TOOL_STYLE_CONFIG, # 获取知识工具
"get_time_date": GET_TIME_DATE_TOOL_STYLE_CONFIG, # 获取时间日期工具 "get_time_date": GET_TIME_DATE_TOOL_STYLE_CONFIG, # 获取时间日期工具
"lpm_get_knowledge_tool": LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG, # LPMM获取知识工具 "lpm_get_knowledge_tool": LPMM_GET_KNOWLEDGE_TOOL_STYLE_CONFIG, # LPMM获取知识工具
"observation": OBSERVATION_STYLE_CONFIG, # 聊天观察
"message_buffer": MESSAGE_BUFFER_STYLE_CONFIG, # 消息缓冲 "message_buffer": MESSAGE_BUFFER_STYLE_CONFIG, # 消息缓冲
"chat_message": CHAT_MESSAGE_STYLE_CONFIG, # 聊天消息 "chat_message": CHAT_MESSAGE_STYLE_CONFIG, # 聊天消息
"chat_image": CHAT_IMAGE_STYLE_CONFIG, # 聊天图片 "chat_image": CHAT_IMAGE_STYLE_CONFIG, # 聊天图片