Team Ai
Apppublic

24f3001764/llm_code_deployment

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
llm_generator.py214 linesDownload Raw Back to src
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