fix
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
__pycache__
|
||||||
|
workspace
|
||||||
161
RUN_STREAMLIT.md
Normal file
161
RUN_STREAMLIT.md
Normal 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/` 目录中。
|
||||||
@@ -411,6 +411,74 @@ def display_chat_flow():
|
|||||||
""", unsafe_allow_html=True)
|
""", 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):
|
def create_agents(api_key: str, base_url: str, model: str):
|
||||||
"""创建所有 Agent"""
|
"""创建所有 Agent"""
|
||||||
llm_config = get_llm_config(model=model, api_key=api_key, base_url=base_url)
|
llm_config = get_llm_config(model=model, api_key=api_key, base_url=base_url)
|
||||||
@@ -526,6 +594,34 @@ def main():
|
|||||||
mime="application/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()
|
display_agent_status_row()
|
||||||
st.divider()
|
st.divider()
|
||||||
@@ -631,7 +727,15 @@ def main():
|
|||||||
# 完成
|
# 完成
|
||||||
add_message("Orchestrator", "✅ SDLC 流程完成!所有任务已完成。", "总结完成")
|
add_message("Orchestrator", "✅ 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 工作流完成!查看上方的对话流了解详情。")
|
progress_placeholder.success("✅ SDLC 工作流完成!查看上方的对话流了解详情。")
|
||||||
|
|
||||||
st.session_state.is_running = False
|
st.session_state.is_running = False
|
||||||
|
|
||||||
st.rerun()
|
st.rerun()
|
||||||
|
|||||||
Reference in New Issue
Block a user