Spaces:
Running
Running
| # 需求:实现 Gradio 应用的动态生成与预览 | |
| - **需求描述:** | |
| 在“代码生成”功能区,当用户选择“Gradio 应用”类型时,系统应能接收用户的自然语言需求,调用 AI 模型生成完整的、可运行的 Gradio 应用代码,并在预览区实时展示该应用。 | |
| - **实现方案:** | |
| 我们将借鉴 `anycoder` 项目的“代码提取 -> 外部执行 -> 界面嵌入”的成熟方案,以确保功能的安全性和稳定性。 | |
| 1. **System Prompt 设计:** | |
| - 创建一个专门的 `get_gradio_sys_prompt` 函数,用于生成指导模型输出完整、可运行的单文件 Gradio 应用的 System Prompt。 | |
| - **强制要求:** | |
| - 模型生成的代码必须是自包含的。 | |
| - Gradio 应用实例必须赋值给一个固定的变量名 `demo`。 | |
| - 脚本必须以 `demo.launch()` 结尾。 | |
| - 输出应仅包含 ```python ... ``` 代码块,无额外解释。 | |
| 2. **后端核心逻辑 (位于 `tab_code.py` 的 `generate_code` 函数中):** | |
| - **子进程管理:** | |
| - 使用一个全局变量 `gradio_process` 来跟踪当前运行的 Gradio 子进程。 | |
| - 在生成新应用前,通过 `gradio_process.terminate()` 和 `gradio_process.join()` 检查并终止任何已存在的旧进程,以释放端口和资源。 | |
| - **动态端口分配:** | |
| - 在 `utils.py` 中实现一个 `find_free_port` 函数,该函数通过 `socket` 库绑定一个临时端口来动态查找一个当前未被占用的 TCP 端口。 | |
| - **代码生成与执行:** | |
| - 从模型返回的流式响应中,实时累积代码,并使用正则表达式 `re.search(r"```python\n(.*?)```", full_code, re.DOTALL)` 提取代码块。 | |
| - 如果未找到代码块,则将整个输出作为代码。 | |
| - **安全检查:** 在执行前,使用 `compile(python_code, '<string>', 'exec')` 验证代码的语法正确性。 | |
| - 将提取的有效代码写入一个临时 Python 文件。 | |
| - 使用 `subprocess.Popen` 在一个隔离的子进程中执行该临时文件,并通过环境变量传递动态分配的端口号。 | |
| - **前端预览:** | |
| - 子进程成功启动后,等待一个固定的时间(例如10秒)以确保 Gradio 服务完全启动。 | |
| - 后端 `yield` 一个包含 `<iframe>` 的 HTML 字符串给前端。 | |
| - `<iframe>` 的 `src` 属性将指向 `http://127.0.0.1:<动态分配的端口号>`,从而将子进程中运行的应用无缝嵌入到主应用的预览区域。 | |
| - **错误处理:** | |
| - 如果代码编译失败,向前端返回详细的错误信息。 | |
| - **创建时间:** 2025-10-11-21-09 | |
| - **状态:** `已完成 (Done)` | |
| - **重要性:** 中等 (Medium) | |
| - **验证方式:** | |
| 1. 启动应用,进入“代码生成”标签页。 | |
| 2. 选择“Gradio 应用”类型。 | |
| 3. 输入“创建一个简单的 Gradio 应用,包含一个输入框和一个输出框”,点击“生成代码”。 | |
| 4. 观察状态显示区域和预览区域。 | |
| 5. 等待生成完成。 | |
| - **验证结果:** | |
| - 成功生成了一个简单的 Gradio 应用,该应用回显用户输入。 | |
| - 在“生成的源代码”标签页中,确认了生成的代码是一个简单的回显应用。 | |
| - 在“实时预览”标签页中,对应用进行了测试,输入 "Hello, World!",得到了正确的输出 "Hello, World!"。 | |
| - 确认了该功能确实对接了 LLM 并能生成有效的、功能性的 Gradio 应用。 | |
| - 功能符合预期。 | |