第一次提交

This commit is contained in:
2026-03-12 13:27:03 +08:00
commit 27fba7a7cc
26 changed files with 6323 additions and 0 deletions

192
utils/logger.py Normal file
View File

@@ -0,0 +1,192 @@
"""
日志工具模块 - 记录多智能体对话历史和系统事件
"""
import os
import json
import logging
from datetime import datetime
from typing import Dict, List, Any, Optional
from pathlib import Path
class ConversationLogger:
"""对话历史日志记录器"""
def __init__(self, log_dir: str = "logs"):
"""
初始化日志记录器
Args:
log_dir: 日志目录
"""
self.log_dir = Path(log_dir)
self.log_dir.mkdir(parents=True, exist_ok=True)
# 创建会话 ID
self.session_id = datetime.now().strftime("%Y%m%d_%H%M%S")
self.log_file = self.log_dir / f"session_{self.session_id}.jsonl"
# 配置日志
self.logger = logging.getLogger(f"autogen_sdls_{self.session_id}")
self.logger.setLevel(logging.INFO)
# 文件处理器
file_handler = logging.FileHandler(self.log_file, encoding='utf-8')
file_handler.setLevel(logging.INFO)
# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 格式化器
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)
self.logger.addHandler(file_handler)
self.logger.addHandler(console_handler)
# 对话历史
self.conversation_history: List[Dict[str, Any]] = []
def log_message(
self,
agent_name: str,
message: str,
role: str = "assistant",
metadata: Optional[Dict] = None
):
"""
记录单条消息
Args:
agent_name: Agent 名称
message: 消息内容
role: 角色user/assistant/system
metadata: 额外元数据
"""
entry = {
"timestamp": datetime.now().isoformat(),
"session_id": self.session_id,
"agent_name": agent_name,
"role": role,
"message": message,
"metadata": metadata or {}
}
self.conversation_history.append(entry)
# 写入 JSONL 文件
with open(self.log_file, 'a', encoding='utf-8') as f:
f.write(json.dumps(entry, ensure_ascii=False) + '\n')
self.logger.info(f"[{agent_name}] {message[:100]}...")
def log_event(self, event_type: str, description: str, data: Optional[Dict] = None):
"""
记录系统事件
Args:
event_type: 事件类型
description: 事件描述
data: 相关数据
"""
entry = {
"timestamp": datetime.now().isoformat(),
"session_id": self.session_id,
"event_type": event_type,
"description": description,
"data": data or {}
}
with open(self.log_file, 'a', encoding='utf-8') as f:
f.write(json.dumps(entry, ensure_ascii=False) + '\n')
self.logger.info(f"[EVENT] {event_type}: {description}")
def get_conversation_history(self) -> List[Dict[str, Any]]:
"""获取完整的对话历史"""
return self.conversation_history
def export_to_json(self, output_path: Optional[str] = None) -> str:
"""
导出对话历史为 JSON 格式
Args:
output_path: 输出路径,默认在 logs 目录下
Returns:
导出文件的路径
"""
if output_path is None:
output_path = self.log_dir / f"conversation_{self.session_id}.json"
else:
output_path = Path(output_path)
export_data = {
"session_id": self.session_id,
"created_at": datetime.now().isoformat(),
"total_messages": len(self.conversation_history),
"conversation": self.conversation_history
}
with open(output_path, 'w', encoding='utf-8') as f:
json.dump(export_data, f, ensure_ascii=False, indent=2)
self.logger.info(f"对话历史已导出到:{output_path}")
return str(output_path)
def export_to_markdown(self, output_path: Optional[str] = None) -> str:
"""
导出对话历史为 Markdown 格式
Args:
output_path: 输出路径
Returns:
导出文件的路径
"""
if output_path is None:
output_path = self.log_dir / f"conversation_{self.session_id}.md"
else:
output_path = Path(output_path)
with open(output_path, 'w', encoding='utf-8') as f:
f.write(f"# AutoGen SDLC 对话历史\n\n")
f.write(f"**会话 ID**: {self.session_id}\n")
f.write(f"**创建时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
f.write(f"**总消息数**: {len(self.conversation_history)}\n\n")
f.write("---\n\n")
for entry in self.conversation_history:
timestamp = entry["timestamp"][:19].replace('T', ' ')
agent = entry["agent_name"]
message = entry["message"]
f.write(f"### [{timestamp}] {agent}\n\n")
f.write(f"{message}\n\n")
f.write("---\n\n")
self.logger.info(f"对话历史已导出为 Markdown: {output_path}")
return str(output_path)
# 全局日志实例
_global_logger: Optional[ConversationLogger] = None
def get_logger(log_dir: str = "logs") -> ConversationLogger:
"""获取或创建全局日志记录器"""
global _global_logger
if _global_logger is None:
_global_logger = ConversationLogger(log_dir)
return _global_logger
def reset_logger():
"""重置全局日志记录器"""
global _global_logger
_global_logger = None