fix:调整目录结构,优化hfc prompt,移除日程,移除动态和llm判断willing模式,

This commit is contained in:
SengokuCola
2025-05-13 18:37:55 +08:00
parent 6376da0682
commit fed71bccad
131 changed files with 422 additions and 1500 deletions

View File

@@ -0,0 +1,307 @@
import time
import os
import json
from typing import List, Optional, Dict, Any
class CycleDetail:
"""循环信息记录类"""
def __init__(self, cycle_id: int):
self.cycle_id = cycle_id
self.start_time = time.time()
self.end_time: Optional[float] = None
self.action_taken = False
self.action_type = "unknown"
self.reasoning = ""
self.timers: Dict[str, float] = {}
self.thinking_id = ""
self.replanned = False
# 添加响应信息相关字段
self.response_info: Dict[str, Any] = {
"response_text": [], # 回复的文本列表
"emoji_info": "", # 表情信息
"anchor_message_id": "", # 锚点消息ID
"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]:
"""将循环信息转换为字典格式"""
return {
"cycle_id": self.cycle_id,
"start_time": self.start_time,
"end_time": self.end_time,
"action_taken": self.action_taken,
"action_type": self.action_type,
"reasoning": self.reasoning,
"timers": self.timers,
"thinking_id": self.thinking_id,
"response_info": self.response_info,
"submind_info": self.submind_info,
"tooluse_info": self.tooluse_info,
"planner_info": self.planner_info,
}
def complete_cycle(self):
"""完成循环,记录结束时间"""
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):
"""设置思考消息ID"""
self.thinking_id = thinking_id
def set_response_info(
self,
response_text: Optional[List[str]] = None,
emoji_info: Optional[str] = None,
anchor_message_id: Optional[str] = None,
reply_message_ids: Optional[List[str]] = None,
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
def list_cycles(stream_id: str, base_dir: str = "log_debug") -> List[str]:
"""
列出指定stream_id的所有循环文件
参数:
stream_id: 聊天流ID
base_dir: 基础目录默认为log_debug
返回:
List[str]: 文件路径列表
"""
try:
stream_dir = os.path.join(base_dir, stream_id)
if not os.path.exists(stream_dir):
return []
files = [
os.path.join(stream_dir, f)
for f in os.listdir(stream_dir)
if f.startswith("cycle_") and f.endswith(".txt")
]
return sorted(files)
except Exception as e:
print(f"列出循环文件时出错: {e}")
return []