faizee07's picture
Update app.py
bb4e6ce verified
raw
history blame
6.84 kB
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()