Spaces:
Runtime error
Runtime error
| import os | |
| import gradio as gr | |
| from crewai import Agent, Task, Crew, Process | |
| from crewai_tools import DuckDuckGoSearchTool, FileWriteTool # CORRECTED IMPORT | |
| from langchain_google_genai import ChatGoogleGenerativeAI | |
| # --- 1. SET UP THE GEMINI LLM --- | |
| # IMPORTANT: Set your Google API key in your environment variables. | |
| # For local testing, create a .env file with: GOOGLE_API_KEY="your_key_here" | |
| # On Hugging Face Spaces, set this in the "Secrets" section. | |
| try: | |
| llm = ChatGoogleGenerativeAI(model="gemini-1.5-flash", | |
| verbose=True, | |
| temperature=0.6, | |
| google_api_key=os.environ.get("GOOGLE_API_KEY")) | |
| except Exception as e: | |
| print("\n\n---") | |
| print("Error initializing Gemini LLM. Make sure you have set your GOOGLE_API_KEY.") | |
| print("See the README for instructions on how to set up your API key.") | |
| print(f"Error: {e}") | |
| print("---\n\n") | |
| llm = None # Set llm to None to prevent further errors | |
| # --- 2. DEFINE TOOLS AND OUTPUT DIRECTORY --- | |
| search_tool = DuckDuckGoSearchTool() # CORRECTED TOOL NAME | |
| os.makedirs("outputs", exist_ok=True) | |
| file_write_tool = FileWriteTool(file_path="outputs/index.html") | |
| # --- 3. DEFINE THE AGENT TEAM --- | |
| # Agent 1: The Brand Designer | |
| designer = Agent( | |
| role='Principal Brand Designer', | |
| goal='Translate a user\'s "vibe" into a concrete, professional design brief for a website.', | |
| backstory=( | |
| "You are a world-class brand designer with a keen eye for aesthetics. " | |
| "You excel at understanding abstract concepts and turning them into actionable design elements like color palettes, font pairings, and page structures." | |
| ), | |
| verbose=True, | |
| llm=llm, | |
| tools=[search_tool], | |
| allow_delegation=False | |
| ) | |
| # Agent 2: The UI/UX Copywriter | |
| copywriter = Agent( | |
| role='Senior UX Copywriter', | |
| goal='Write compelling, vibe-appropriate copy for all sections of a website based on a design brief.', | |
| backstory=( | |
| "You are an expert copywriter who specializes in creating website content that resonates with the target audience. " | |
| "You know how to craft engaging headlines, informative text, and clear calls-to-action that perfectly match the brand's voice." | |
| ), | |
| verbose=True, | |
| llm=llm, | |
| allow_delegation=False | |
| ) | |
| # Agent 3: The Frontend Developer | |
| developer = Agent( | |
| role='Senior Frontend Developer', | |
| goal='Take a design brief and content map to build a complete, self-contained HTML file with embedded CSS and JavaScript.', | |
| backstory=( | |
| "You are a skilled frontend developer who can build beautiful and functional websites from scratch. " | |
| "You are a master of HTML, CSS, and JavaScript, and you specialize in creating single-file web pages that are easy to deploy and view." | |
| ), | |
| verbose=True, | |
| llm=llm, | |
| tools=[file_write_tool], | |
| allow_delegation=False | |
| ) | |
| # --- 4. DEFINE THE WORKFLOW (TASKS) --- | |
| # Task 1: Create the Design Brief | |
| design_task = Task( | |
| description=( | |
| "Analyze the user's prompt: '{prompt}' to understand the desired vibe. " | |
| "Conduct a web search for inspiration on color palettes, font pairings, and overall aesthetics that match this vibe. " | |
| "Create a comprehensive 'Design Brief' document that includes a color palette (with hex codes), a font pairing (with Google Fonts links), and a detailed page structure (e.g., Navbar, Hero, About, Menu, Contact)." | |
| ), | |
| expected_output=( | |
| "A structured markdown document containing the complete Design Brief, including sections for Color Palette, Font Pairing, and Page Structure." | |
| ), | |
| agent=designer | |
| ) | |
| # Task 2: Write the Website Content | |
| copywriting_task = Task( | |
| description=( | |
| "Using the Design Brief provided, write all the necessary text content for the website. " | |
| "Ensure the tone of the copy perfectly matches the specified vibe. Create placeholder content for all sections, including the menu and contact form." | |
| ), | |
| expected_output=( | |
| "A structured markdown document called a 'Content Map' that lists the text content for each section of the website (e.g., hero_title, about_text, menu_items)." | |
| ), | |
| agent=copywriter, | |
| context=[design_task] # This task depends on the design_task | |
| ) | |
| # Task 3: Build the HTML Website | |
| development_task = Task( | |
| description=( | |
| "Based on the final Design Brief and the Content Map, create a complete, single-file HTML website. " | |
| "The HTML file must be self-contained, with all CSS and any simple JavaScript embedded within the file in <style> and <script> tags. " | |
| "Use the specified color palette and Google Fonts. Populate the HTML with the exact content from the Content Map. " | |
| "Your final output MUST be only the code for the HTML file." | |
| ), | |
| expected_output=( | |
| "The complete and final HTML code for the website, written to the file 'outputs/index.html'." | |
| ), | |
| agent=developer, | |
| context=[design_task, copywriting_task], # This task depends on the previous two | |
| tools=[file_write_tool] | |
| ) | |
| # --- 5. ASSEMBLE THE CREW --- | |
| vibe_crew = Crew( | |
| agents=[designer, copywriter, developer], | |
| tasks=[design_task, copywriting_task, development_task], | |
| process=Process.sequential, | |
| verbose=2 | |
| ) | |
| # --- 6. CREATE THE GRADIO WEB INTERFACE --- | |
| def run_crew(prompt): | |
| if llm is None: | |
| return "Error: Gemini LLM not initialized. Please check your API key.", None, None | |
| # Clear previous output file | |
| if os.path.exists("outputs/index.html"): | |
| os.remove("outputs/index.html") | |
| inputs = {'prompt': prompt} | |
| result = vibe_crew.kickoff(inputs=inputs) | |
| # Read the generated HTML file | |
| try: | |
| with open("outputs/index.html", "r") as file: | |
| html_content = file.read() | |
| return result, html_content, "outputs/index.html" | |
| except FileNotFoundError: | |
| return result, "Error: Output file not found. The developer agent might have failed.", None | |
| iface = gr.Interface( | |
| fn=run_crew, | |
| inputs=gr.Textbox( | |
| lines=3, | |
| placeholder="e.g., A website for my new coffee shop in Brooklyn. The vibe should be cozy, rustic, and artisanal." | |
| ), | |
| outputs=[ | |
| gr.Markdown(label="Crew Final Report"), | |
| gr.Code(label="Generated HTML Code", language="html"), | |
| gr.File(label="Download Website") | |
| ], | |
| title="🎨 Vibe Coder AI", | |
| description="Enter the 'vibe' for your website, and this multi-agent team will design, write, and code a complete webpage for you using Gemini.", | |
| examples=[ | |
| ["A personal portfolio for a photographer. The vibe should be minimalist, modern, and clean."], | |
| ["A landing page for a new tech startup focused on AI. The vibe is futuristic, sleek, and professional."], | |
| ["A website for a local bakery. The vibe is warm, friendly, and homemade."] | |
| ], | |
| allow_flagging="never" | |
| ) | |
| if __name__ == "__main__": | |
| iface.launch() | |