feat:添加了focus的logger记录,修复潜在的bar request400,为表达器读取配置文件

This commit is contained in:
SengokuCola
2025-05-30 12:18:01 +08:00
parent 54724ae21e
commit 78df7ab553
8 changed files with 95 additions and 53 deletions

View File

@@ -2,12 +2,14 @@ import time
import os
from typing import List, Optional, Dict, Any
log_dir = "log/log_cycle_debug/"
class CycleDetail:
"""循环信息记录类"""
def __init__(self, cycle_id: int):
self.cycle_id = cycle_id
self.prefix = ""
self.thinking_id = ""
self.start_time = time.time()
self.end_time: Optional[float] = None
@@ -21,21 +23,71 @@ class CycleDetail:
def to_dict(self) -> Dict[str, Any]:
"""将循环信息转换为字典格式"""
def convert_to_serializable(obj, depth=0, seen=None):
if seen is None:
seen = set()
# 防止递归过深
if depth > 5: # 降低递归深度限制
return str(obj)
# 防止循环引用
obj_id = id(obj)
if obj_id in seen:
return str(obj)
seen.add(obj_id)
try:
if hasattr(obj, 'to_dict'):
# 对于有to_dict方法的对象直接调用其to_dict方法
return obj.to_dict()
elif isinstance(obj, dict):
# 对于字典,只保留基本类型和可序列化的值
return {k: convert_to_serializable(v, depth + 1, seen)
for k, v in obj.items()
if isinstance(k, (str, int, float, bool))}
elif isinstance(obj, (list, tuple)):
# 对于列表和元组,只保留可序列化的元素
return [convert_to_serializable(item, depth + 1, seen)
for item in obj
if not isinstance(item, (dict, list, tuple)) or
isinstance(item, (str, int, float, bool, type(None)))]
elif isinstance(obj, (str, int, float, bool, type(None))):
return obj
else:
return str(obj)
finally:
seen.remove(obj_id)
return {
"cycle_id": self.cycle_id,
"start_time": self.start_time,
"end_time": self.end_time,
"timers": self.timers,
"thinking_id": self.thinking_id,
"loop_observation_info": self.loop_observation_info,
"loop_process_info": self.loop_process_info,
"loop_plan_info": self.loop_plan_info,
"loop_action_info": self.loop_action_info,
"loop_observation_info": convert_to_serializable(self.loop_observation_info),
"loop_process_info": convert_to_serializable(self.loop_process_info),
"loop_plan_info": convert_to_serializable(self.loop_plan_info),
"loop_action_info": convert_to_serializable(self.loop_action_info),
}
def complete_cycle(self):
"""完成循环,记录结束时间"""
self.end_time = time.time()
current_time_minute = time.strftime("%Y%m%d_%H%M", time.localtime())
self.log_cycle_to_file(log_dir + self.prefix + f"/{current_time_minute}_cycle_" + str(self.cycle_id) + ".json")
def log_cycle_to_file(self, file_path: str):
"""将循环信息写入文件"""
# 如果目录不存在,则创建目录
dir_name = os.path.dirname(file_path)
if dir_name and not os.path.exists(dir_name):
os.makedirs(dir_name, exist_ok=True)
# 写入文件
import json
with open(file_path, "a", encoding="utf-8") as f:
f.write(json.dumps(self.to_dict(), ensure_ascii=False) + "\n")
def set_thinking_id(self, thinking_id: str):
"""设置思考消息ID"""
@@ -47,30 +99,3 @@ class CycleDetail:
self.loop_processor_info = loop_info["loop_processor_info"]
self.loop_plan_info = loop_info["loop_plan_info"]
self.loop_action_info = loop_info["loop_action_info"]
@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 []