diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ff1f7ce --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +workspace \ No newline at end of file diff --git a/RUN_STREAMLIT.md b/RUN_STREAMLIT.md new file mode 100644 index 0000000..0f87011 --- /dev/null +++ b/RUN_STREAMLIT.md @@ -0,0 +1,161 @@ +# Streamlit 运行说明 + +## 📂 生成的代码在哪里? + +当您运行 `streamlit run frontend/streamlit_app_v3.py` 并启动 SDLC 工作流后,所有生成的文件都保存在: + +``` +c:\Workspace\AI_AutoGen\workspace\ +``` + +## 📁 目录结构 + +``` +c:\Workspace\AI_AutoGen/ +├── workspace/ ← 生成的代码在这里! +│ ├── SRS.md # 软件需求规格说明书 +│ ├── test_battery_health.py # 测试用例 +│ ├── src_battery_health.py # 源代码 +│ ├── bdd_scenarios.md # BDD 测试场景 +│ ├── coverage_report.md # 测试覆盖率报告 +│ └── FINAL_REPORT.md # 最终项目报告 +├── logs/ ← 对话日志 +│ └── session_*.jsonl # 会话日志 +└── frontend/ + └── streamlit_app_v3.py +``` + +## 🔍 如何查看生成的文件 + +### 方法 1: 在 Streamlit 界面查看(推荐) + +运行 Streamlit 后,在界面右侧边栏会显示: +- **"生成的文件"** 区域 +- 点击文件名可以预览内容 +- 支持查看 `.md`, `.py`, `.txt` 等格式 + +### 方法 2: 直接在文件管理器查看 + +**Windows:** +```powershell +# 打开 workspace 目录 +explorer c:\Workspace\AI_AutoGen\workspace +``` + +**命令行查看:** +```bash +# 查看所有生成的文件 +dir c:\Workspace\AI_AutoGen\workspace + +# 查看 SRS 文档 +type c:\Workspace\AI_AutoGen\workspace\SRS.md + +# 查看源代码 +type c:\Workspace\AI_AutoGen\workspace\src_battery_health.py +``` + +### 方法 3: 使用 Python 脚本查看 + +创建一个快速查看脚本: + +```python +# view_generated_files.py +from pathlib import Path + +workspace = Path("workspace") +if workspace.exists(): + print("生成的文件列表:") + for file in workspace.glob("*"): + if file.is_file(): + print(f" 📄 {file.name} ({file.stat().st_size:,} bytes)") +else: + print("workspace 目录不存在,请先运行 SDLC 工作流") +``` + +## 🎯 典型生成的文件 + +运行一次完整的 SDLC 工作流后,通常会生成以下文件: + +| 文件名 | 类型 | 说明 | 生成 Agent | +|--------|------|------|-----------| +| `SRS.md` | Markdown | 软件需求规格说明书 | PM Agent | +| `test_*.py` | Python | 测试用例脚本 | QA Agent | +| `src_*.py` | Python | 源代码实现 | Dev Agent | +| `bdd_scenarios.md` | Markdown | BDD 测试场景 | QA Agent | +| `coverage_report.md` | Markdown | 测试覆盖率报告 | QA Agent | +| `FINAL_REPORT.md` | Markdown | 最终项目总结 | Orchestrator | + +## 💡 示例:查看生成的代码 + +假设您运行了"电池健康预测 API"的示例,生成的代码会在: + +**源代码位置:** +``` +c:\Workspace\AI_AutoGen\workspace\src_battery_health.py +``` + +**测试代码位置:** +``` +c:\Workspace\AI_AutoGen\workspace\test_battery_health.py +``` + +**需求文档位置:** +``` +c:\Workspace\AI_AutoGen\workspace\SRS.md +``` + +## 🔧 在 Streamlit 中添加文件查看器 + +如果想要在 Streamlit 界面中直接查看生成的文件,可以在 `streamlit_app_v3.py` 中添加以下代码: + +```python +# 在 sidebar 中添加 +st.sidebar.subheader("📁 生成的文件") + +workspace_dir = Path("workspace") +if workspace_dir.exists(): + files = list(workspace_dir.glob("*")) + for file in files: + if file.is_file(): + with st.sidebar.expander(f"📄 {file.name}"): + try: + content = file.read_text(encoding='utf-8') + st.code(content[:1000] + ("..." if len(content) > 1000 else "")) + + # 下载按钮 + st.download_button( + label="⬇️ 下载", + data=content, + file_name=file.name, + mime="text/plain" + ) + except Exception as e: + st.error(f"读取失败:{e}") +else: + st.sidebar.info("工作目录为空,请先运行工作流") +``` + +## ⚠️ 注意事项 + +1. **首次运行会创建目录** - workspace 目录会在第一次运行时自动创建 +2. **文件会覆盖** - 每次运行新的需求会覆盖之前的文件 +3. **及时备份** - 重要的生成物请及时复制到其他目录 +4. **日志目录** - 对话历史保存在 `logs/` 目录,格式为 JSONL + +## 📊 查看对话日志 + +对话日志保存在 `logs/` 目录: + +```bash +# 查看最新的会话日志 +dir c:\Workspace\AI_AutoGen\logs\session_*.jsonl + +# 使用 Python 查看 +python -c "import json; [print(json.loads(line)) for line in open('logs/session_*.jsonl')]" +``` + +--- + +**🎉 现在您知道生成的代码在哪里了!** + +运行 `streamlit run frontend/streamlit_app_v3.py` 后,所有生成的文件都会出现在 `workspace/` 目录中。 diff --git a/frontend/streamlit_app_v3.py b/frontend/streamlit_app_v3.py index 7f46a30..a90c22a 100644 --- a/frontend/streamlit_app_v3.py +++ b/frontend/streamlit_app_v3.py @@ -411,6 +411,74 @@ def display_chat_flow(): """, unsafe_allow_html=True) +def save_generated_files(): + """从对话中提取并保存生成的文件到 workspace 目录""" + workspace_dir = Path("workspace") + workspace_dir.mkdir(parents=True, exist_ok=True) + + files_saved = [] + + # 遍历所有消息,提取文件内容 + for msg in st.session_state.messages: + content = msg.get("content", "") + agent_key = msg.get("agent_key", "") + + # PM Agent 生成 SRS.md + if agent_key == "PM_Agent" and ("SRS" in content or "软件需求规格" in content): + srs_file = workspace_dir / "SRS.md" + # 提取 SRS 内容(查找包含 FR- 或 NFR- 的段落) + srs_content = content + if "功能性需求" in content: + srs_content = content[content.find("功能性需求"):] + with open(srs_file, 'w', encoding='utf-8') as f: + f.write(f"# 软件需求规格说明书 (SRS)\n\n") + f.write(f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n") + f.write(srs_content) + files_saved.append(str(srs_file)) + + # QA Agent 生成测试文件 + if agent_key == "QA_Agent" and ("test_" in content or "def test_" in content): + test_file = workspace_dir / "test_battery_health.py" + # 提取 Python 代码 + if "```python" in content: + code = content.split("```python")[1].split("```")[0] + else: + code = content + with open(test_file, 'w', encoding='utf-8') as f: + f.write(f'"""\n电池健康状态测试用例\n生成时间:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}\n"""\n\n') + f.write(code) + files_saved.append(str(test_file)) + + # Dev Agent 生成源代码 + if agent_key == "Dev_Agent" and ("def " in content or "class " in content): + src_file = workspace_dir / "src_battery_health.py" + # 提取 Python 代码 + if "```python" in content: + code = content.split("```python")[1].split("```")[0] + else: + code = content + with open(src_file, 'w', encoding='utf-8') as f: + f.write(f'"""\n电池健康状态计算模块\n生成时间:{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}\n"""\n\n') + f.write(code) + files_saved.append(str(src_file)) + + # Orchestrator 生成最终报告 + if agent_key == "Orchestrator" and ("完成" in content and "SDLC" in content): + report_file = workspace_dir / "FINAL_REPORT.md" + with open(report_file, 'w', encoding='utf-8') as f: + f.write(f"# SDLC 项目最终报告\n\n") + f.write(f"**生成时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n") + f.write("## 项目概述\n\n") + f.write("基于 AutoGen 多智能体系统完成的软件交付项目。\n\n") + f.write("## 生成文件列表\n\n") + for i, saved_file in enumerate(files_saved, 1): + f.write(f"{i}. {saved_file}\n") + f.write(f"\n## 项目总结\n\n{content}\n") + files_saved.append(str(report_file)) + + return files_saved + + def create_agents(api_key: str, base_url: str, model: str): """创建所有 Agent""" llm_config = get_llm_config(model=model, api_key=api_key, base_url=base_url) @@ -525,6 +593,34 @@ def main(): file_name=f"agent_chat_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", mime="application/json" ) + + st.divider() + + # 显示生成的文件 + st.subheader("📁 生成的文件") + workspace_dir = Path("workspace") + if workspace_dir.exists(): + files = list(workspace_dir.glob("*")) + if files: + for file in files: + if file.is_file(): + with st.expander(f"📄 {file.name}"): + try: + content = file.read_text(encoding='utf-8') + st.code(content[:500] + ("..." if len(content) > 500 else "")) + st.download_button( + label="⬇️ 下载", + data=content, + file_name=file.name, + mime="text/plain", + key=f"download_{file.name}" + ) + except Exception as e: + st.error(f"读取失败:{e}") + else: + st.info("工作目录为空,请先运行工作流") + else: + st.info("工作目录不存在") # 主界面 display_agent_status_row() @@ -631,7 +727,15 @@ def main(): # 完成 add_message("Orchestrator", "✅ SDLC 流程完成!所有任务已完成。", "总结完成") - progress_placeholder.success("✅ SDLC 工作流完成!查看上方的对话流了解详情。") + # 保存生成的文件 + progress_placeholder.info("💾 正在保存生成的文件...") + saved_files = save_generated_files() + + if saved_files: + progress_placeholder.success(f"✅ SDLC 工作流完成!已保存 {len(saved_files)} 个文件到 workspace/ 目录") + else: + progress_placeholder.success("✅ SDLC 工作流完成!查看上方的对话流了解详情。") + st.session_state.is_running = False st.rerun()