24f3001764/llm_code_deployment
0
1import os2from pathlib import Path3from typing import List4from openai import OpenAI5from src.config import config6import aiofiles7 8 9class LLMAppGenerator:10 """Generate web applications using LLM"""11 12 def __init__(self):13 self.client = OpenAI(14 api_key=config.OPENAI_API_KEY,15 base_url=config.OPENAI_BASE_URL16 )17 18 async def generate_app(19 self, 20 brief: str, 21 checks: List[str], 22 attachments: List[Path],23 task_id: str24 ) -> Path:25 """Generate a complete web app based on the brief"""26 27 # Create output directory28 app_dir = Path(config.GENERATED_APPS_DIR) / task_id29 app_dir.mkdir(parents=True, exist_ok=True)30 31 # Build prompt32 prompt = self._build_prompt(brief, checks, attachments)33 34 # Generate HTML35 html_content = await self._generate_html(prompt)36 37 # Save index.html38 index_path = app_dir / "index.html"39 async with aiofiles.open(index_path, 'w', encoding='utf-8') as f:40 await f.write(html_content)41 42 # Generate README43 readme_content = await self._generate_readme(brief, task_id)44 readme_path = app_dir / "README.md"45 async with aiofiles.open(readme_path, 'w', encoding='utf-8') as f:46 await f.write(readme_content)47 48 return app_dir49 50 def _build_prompt(self, brief: str, checks: List[str], attachments: List[Path]) -> str:51 """Build prompt for LLM"""52 attachment_info = ""53 if attachments:54 attachment_names = [att.name for att in attachments]55 attachment_info = f"\n\nAttachments provided: {', '.join(attachment_names)}"56 57 checks_text = "\n".join([f"- {check}" for check in checks])58 59 return f"""Create a complete, self-contained single-page web application (HTML with embedded CSS and JavaScript).60 61**Requirements:**62{brief}63 64**Evaluation Criteria:**65{checks_text}66{attachment_info}67 68**Instructions:**691. Create a modern, responsive UI using HTML5, CSS3, and vanilla JavaScript702. Handle URL parameters (e.g., ?url=...) as specified713. Include error handling and loading states724. Make it visually appealing with good UX735. Add clear instructions for users746. Ensure all functionality works client-side757. Use modern web APIs and best practices76 77Return ONLY the complete HTML file content, no explanations."""78 79 async def _generate_html(self, prompt: str) -> str:80 """Call OpenAI API to generate HTML"""81 try:82 response = self.client.chat.completions.create(83 model="gpt-4-turbo-preview",84 messages=[85 {"role": "system", "content": "You are an expert web developer. Generate clean, modern, production-ready HTML/CSS/JS code."},86 {"role": "user", "content": prompt}87 ],88 temperature=0.7,89 max_tokens=400090 )91 92 html_content = response.choices[0].message.content93 94 # Clean up markdown code blocks if present95 if "```html" in html_content:96 html_content = html_content.split("```html")[1].split("```")[0].strip()97 elif "```" in html_content:98 html_content = html_content.split("```")[1].split("```")[0].strip()99 100 return html_content101 102 except Exception as e:103 # Fallback to basic template104 return self._get_fallback_template(prompt)105 106 async def _generate_readme(self, brief: str, task_id: str) -> str:107 """Generate professional README"""108 prompt = f"""Create a professional README.md for a web application with these details:109 110**Brief:** {brief}111**Task ID:** {task_id}112 113Include these sections:1141. Project title and brief description1152. Features1163. Setup instructions (how to run locally)1174. Usage instructions (how to use the app)1185. Code explanation (brief technical overview)1196. License (MIT)120 121Keep it concise and professional. Use Markdown formatting."""122 123 try:124 response = self.client.chat.completions.create(125 model="gpt-4-turbo-preview",126 messages=[127 {"role": "system", "content": "You are a technical writer creating clear, professional documentation."},128 {"role": "user", "content": prompt}129 ],130 temperature=0.7,131 max_tokens=1500132 )133 134 readme = response.choices[0].message.content135 136 # Clean up markdown code blocks if present137 if "```markdown" in readme:138 readme = readme.split("```markdown")[1].split("```")[0].strip()139 elif "```" in readme:140 readme = readme.split("```")[1].split("```")[0].strip()141 142 return readme143 144 except Exception as e:145 return self._get_fallback_readme(brief, task_id)146 147 def _get_fallback_template(self, brief: str) -> str:148 """Fallback HTML template if API fails"""149 return f"""<!DOCTYPE html>150<html lang="en">151<head>152 <meta charset="UTF-8">153 <meta name="viewport" content="width=device-width, initial-scale=1.0">154 <title>Generated App</title>155 <style>156 * {{ margin: 0; padding: 0; box-sizing: border-box; }}157 body {{158 font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;159 background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);160 min-height: 100vh;161 display: flex;162 align-items: center;163 justify-content: center;164 padding: 20px;165 }}166 .container {{167 background: white;168 border-radius: 12px;169 padding: 40px;170 max-width: 600px;171 width: 100%;172 box-shadow: 0 20px 60px rgba(0,0,0,0.3);173 }}174 h1 {{ color: #333; margin-bottom: 20px; }}175 p {{ color: #666; line-height: 1.6; margin-bottom: 20px; }}176 .brief {{ background: #f5f5f5; padding: 15px; border-radius: 8px; margin-top: 20px; }}177 </style>178</head>179<body>180 <div class="container">181 <h1>Generated Application</h1>182 <p>This application was automatically generated based on the following requirements:</p>183 <div class="brief">184 <strong>Brief:</strong><br>185 {brief}186 </div>187 <p style="margin-top: 20px; font-size: 14px; color: #999;">188 Note: This is a placeholder. The full application will be generated by the LLM.189 </p>190 </div>191</body>192</html>"""193 194 def _get_fallback_readme(self, brief: str, task_id: str) -> str:195 """Fallback README if API fails"""196 return f"""# {task_id}197 198## Description199{brief}200 201## Setup2021. Clone this repository2032. Open `index.html` in a web browser204 205## Usage206Open the application in your browser and follow the on-screen instructions.207 208## Technical Details209This is a single-page web application built with HTML, CSS, and JavaScript.210 211## License212MIT License - see LICENSE file for details213"""214 