This commit is contained in:
2026-03-12 14:16:27 +08:00
parent 27fba7a7cc
commit cf46f77224
3 changed files with 268 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
__pycache__
workspace

161
RUN_STREAMLIT.md Normal file
View File

@@ -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/` 目录中。

View File

@@ -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)
@@ -526,6 +594,34 @@ def main():
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()
st.divider()
@@ -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()