fix
This commit is contained in:
@@ -7,6 +7,8 @@ import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, Any, Optional, List
|
||||
import json
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
# 添加项目根目录到路径
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
@@ -23,6 +25,81 @@ from utils.logger import get_logger
|
||||
from utils.callback_handler import get_callback_handler
|
||||
|
||||
|
||||
def extract_code(content):
|
||||
"""从 Markdown 代码块中提取纯代码"""
|
||||
if "```python" in content:
|
||||
parts = content.split("```python")
|
||||
if len(parts) > 1:
|
||||
code = parts[1].split("```")[0].strip()
|
||||
return code
|
||||
elif "```" in content:
|
||||
parts = content.split("```")
|
||||
if len(parts) > 1:
|
||||
code = parts[1].strip()
|
||||
return code
|
||||
return content
|
||||
|
||||
|
||||
def save_file_from_content(content: str, agent_name: str, workspace_dir: Path) -> List[str]:
|
||||
"""
|
||||
根据 Agent 的内容实时保存文件
|
||||
|
||||
Args:
|
||||
content: Agent 的输出内容
|
||||
agent_name: Agent 名称
|
||||
workspace_dir: 工作目录
|
||||
|
||||
Returns:
|
||||
保存的文件路径列表
|
||||
"""
|
||||
saved_files = []
|
||||
|
||||
# PM Agent 生成 SRS
|
||||
if agent_name == "PM_Agent" and ("需求" in content or "SRS" in content or "软件需求规格说明书" in content):
|
||||
file = workspace_dir / "SRS.md"
|
||||
with open(file, "w", encoding="utf-8") as f:
|
||||
f.write(f"# 软件需求规格说明书\n\n生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
|
||||
f.write(content)
|
||||
saved_files.append(str(file))
|
||||
print(f"💾 [实时保存] {file}")
|
||||
|
||||
# QA Agent 生成测试
|
||||
elif agent_name == "QA_Agent" and ("test" in content.lower() or "测试" in content or "def test_" in content):
|
||||
file = workspace_dir / "test_sample.py"
|
||||
code = extract_code(content)
|
||||
if code: # 确保有代码内容才保存
|
||||
with open(file, "w", encoding="utf-8") as f:
|
||||
f.write(f"# 测试用例\n\n{code}")
|
||||
saved_files.append(str(file))
|
||||
print(f"💾 [实时保存] {file}")
|
||||
|
||||
# Dev Agent 生成代码 - 支持多个文件
|
||||
elif agent_name == "Dev_Agent" and ("def " in content or "class " in content or "import " in content):
|
||||
# 尝试提取带文件名的代码块
|
||||
code_blocks = re.findall(r'```python\s*\n#(?:\s*File:|\s*filename:)?\s*([^\n]+)\n(.*?)```', content, re.DOTALL)
|
||||
|
||||
if code_blocks:
|
||||
# 保存多个文件
|
||||
for filename, code_content in code_blocks:
|
||||
filename = filename.strip()
|
||||
file_path = workspace_dir / filename
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(f"# 生成时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n{code_content}")
|
||||
saved_files.append(str(file_path))
|
||||
print(f"💾 [实时保存] {file_path}")
|
||||
else:
|
||||
# 没有文件名标记,保存为 src_sample.py
|
||||
file = workspace_dir / "src_sample.py"
|
||||
code = extract_code(content)
|
||||
if code: # 确保有代码内容才保存
|
||||
with open(file, "w", encoding="utf-8") as f:
|
||||
f.write(f"# 源代码\n\n{code}")
|
||||
saved_files.append(str(file))
|
||||
print(f"💾 [实时保存] {file}")
|
||||
|
||||
return saved_files
|
||||
|
||||
|
||||
class AutoGenSDLCSystem:
|
||||
"""AutoGen SDLC 多智能体协同系统"""
|
||||
|
||||
@@ -70,7 +147,43 @@ class AutoGenSDLCSystem:
|
||||
# 创建 GroupChat
|
||||
self.groupchat = None
|
||||
self.manager = None
|
||||
|
||||
# 记录已保存的文件
|
||||
self.saved_files = []
|
||||
|
||||
def _on_new_message(self, sender, message, **kwargs):
|
||||
"""
|
||||
新消息回调函数 - 实时保存文件
|
||||
|
||||
Args:
|
||||
sender: 发送者
|
||||
message: 消息内容
|
||||
**kwargs: 其他参数
|
||||
"""
|
||||
try:
|
||||
agent_name = getattr(sender, 'name', 'Unknown')
|
||||
content = message.get('content', '') if isinstance(message, dict) else str(message)
|
||||
|
||||
# 实时保存文件
|
||||
saved_files = save_file_from_content(content, agent_name, self.workspace_dir)
|
||||
|
||||
# 如果有文件保存,记录并通知回调
|
||||
if saved_files:
|
||||
self.saved_files.extend(saved_files)
|
||||
for file_path in saved_files:
|
||||
# 确定文件类型
|
||||
if file_path.endswith('.md'):
|
||||
file_type = 'markdown'
|
||||
elif file_path.endswith('.py'):
|
||||
file_type = 'python'
|
||||
else:
|
||||
file_type = 'other'
|
||||
|
||||
# 触发回调
|
||||
self.callback_handler.on_file_created(agent_name, file_path, file_type)
|
||||
except Exception as e:
|
||||
print(f"⚠️ 实时保存文件时出错:{e}")
|
||||
|
||||
def _create_agents(self):
|
||||
"""创建所有 Agent"""
|
||||
# PM Agent
|
||||
@@ -113,7 +226,7 @@ class AutoGenSDLCSystem:
|
||||
self.user_proxy = UserProxyAgent(
|
||||
name="User_Proxy",
|
||||
human_input_mode="NEVER", # 修复:Web 环境不支持 TERMINAL
|
||||
max_consecutive_auto_reply=0,
|
||||
max_consecutive_auto_reply=10, # 允许连续自动回复,避免提前终止
|
||||
code_execution_config={
|
||||
"work_dir": str(self.workspace_dir),
|
||||
"use_docker": False,
|
||||
@@ -167,6 +280,9 @@ class AutoGenSDLCSystem:
|
||||
# 创建 GroupChat
|
||||
self.create_groupchat(max_round)
|
||||
|
||||
# 重置已保存文件列表
|
||||
self.saved_files = []
|
||||
|
||||
# 构建初始消息
|
||||
initial_message = f"""
|
||||
请启动完整的 SDLC 流程,开发以下功能:
|
||||
@@ -188,7 +304,17 @@ class AutoGenSDLCSystem:
|
||||
"""
|
||||
|
||||
try:
|
||||
# 启动对话
|
||||
# 启动对话 - 使用回调函数实时处理消息
|
||||
print("\n🚀 开始对话...\n")
|
||||
|
||||
# 为每个 Agent 注册实时文件保存回调
|
||||
for agent in [self.pm_agent, self.qa_agent, self.dev_agent, self.orchestrator]:
|
||||
agent.register_reply(
|
||||
self._on_new_message,
|
||||
reply_func_total_count=1,
|
||||
position=0 # 在最前面执行,确保实时保存
|
||||
)
|
||||
|
||||
chat_result = self.user_proxy.initiate_chat(
|
||||
self.manager,
|
||||
message=initial_message,
|
||||
@@ -215,7 +341,8 @@ class AutoGenSDLCSystem:
|
||||
"success": True,
|
||||
"summary": chat_result.summary if hasattr(chat_result, 'summary') else "工作流完成",
|
||||
"messages": self.groupchat.messages,
|
||||
"workspace": str(self.workspace_dir)
|
||||
"workspace": str(self.workspace_dir),
|
||||
"saved_files": self.saved_files
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
@@ -224,57 +351,4 @@ class AutoGenSDLCSystem:
|
||||
"success": False,
|
||||
"error": str(e),
|
||||
"messages": self.groupchat.messages if self.groupchat else []
|
||||
}
|
||||
|
||||
def export_conversation(self, output_path: Optional[str] = None) -> str:
|
||||
"""导出对话历史"""
|
||||
return self.logger.export_to_json(output_path)
|
||||
|
||||
def export_report(self, output_path: Optional[str] = None) -> str:
|
||||
"""导出 Markdown 格式报告"""
|
||||
return self.logger.export_to_markdown(output_path)
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数 - 演示模式"""
|
||||
print("=" * 60)
|
||||
print("AutoGen SDLC 多智能体协同系统")
|
||||
print("=" * 60)
|
||||
|
||||
# 检查 API Key
|
||||
api_key = os.getenv("DASHSCOPE_API_KEY")
|
||||
if not api_key:
|
||||
print("\n❌ 错误:未设置 DASHSCOPE_API_KEY 环境变量")
|
||||
print("请运行:export DASHSCOPE_API_KEY='your_api_key'")
|
||||
return
|
||||
|
||||
# 创建系统实例
|
||||
system = AutoGenSDLCSystem(api_key=api_key)
|
||||
|
||||
# 演示用例
|
||||
demo_requirement = "我需要一个电池健康状态 (SOH) 预测 API,能够接收电池的电压、电流、温度数据,输出健康度百分比"
|
||||
|
||||
print(f"\n📋 演示需求:{demo_requirement}")
|
||||
print("\n🚀 启动 SDLC 工作流...\n")
|
||||
|
||||
# 运行工作流
|
||||
result = system.run_workflow(demo_requirement, max_round=15)
|
||||
|
||||
# 输出结果
|
||||
print("\n" + "=" * 60)
|
||||
if result["success"]:
|
||||
print("✅ 工作流成功完成!")
|
||||
print(f"📄 摘要:{result['summary'][:200]}...")
|
||||
print(f"📂 工作目录:{result['workspace']}")
|
||||
else:
|
||||
print(f"❌ 工作流失败:{result.get('error', '未知错误')}")
|
||||
|
||||
# 导出报告
|
||||
report_path = system.export_report()
|
||||
print(f"📊 对话报告已导出:{report_path}")
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
}
|
||||
Reference in New Issue
Block a user