builder / app.py
mgbam's picture
Upload 6 files
f22daae verified
raw
history blame
7.97 kB
import os
from typing import Dict, List, Optional, Tuple
import gradio as gr
from config import (
AVAILABLE_MODELS, DEMO_LIST, HTML_SYSTEM_PROMPT
)
from api_clients import generation_code, tavily_client
from chat_processing import (
clear_history, history_to_chatbot_messages, update_image_input_visibility,
get_gradio_language, send_to_sandbox
)
def demo_card_click(e: gr.EventData):
try:
# Get the index from the event data
if hasattr(e, '_data') and e._data:
# Try different ways to get the index
if 'index' in e._data:
index = e._data['index']
elif 'component' in e._data and 'index' in e._data['component']:
index = e._data['component']['index']
elif 'target' in e._data and 'index' in e._data['target']:
index = e._data['target']['index']
else:
# If we can't get the index, try to extract it from the card data
index = 0
else:
index = 0
# Ensure index is within bounds
if index >= len(DEMO_LIST):
index = 0
return DEMO_LIST[index]['description']
except (KeyError, IndexError, AttributeError) as e:
# Return the first demo description as fallback
return DEMO_LIST[0]['description']
# Main application
with gr.Blocks(
theme=gr.themes.Base(
primary_hue="blue",
secondary_hue="gray",
neutral_hue="gray",
font=gr.themes.GoogleFont("Inter"),
font_mono=gr.themes.GoogleFont("JetBrains Mono"),
text_size=gr.themes.sizes.text_md,
spacing_size=gr.themes.sizes.spacing_md,
radius_size=gr.themes.sizes.radius_md
),
title="AnyCoder - AI Code Generator"
) as demo:
history = gr.State([])
setting = gr.State({
"system": HTML_SYSTEM_PROMPT,
})
current_model = gr.State(AVAILABLE_MODELS[0]) # Moonshot Kimi-K2
open_panel = gr.State(None)
last_login_state = gr.State(None)
with gr.Sidebar():
input = gr.Textbox(
label="What would you like to build?",
placeholder="Describe your application...",
lines=3,
visible=True # Always visible
)
# Language dropdown for code generation
language_choices = [
"python", "c", "cpp", "markdown", "latex", "json", "html", "css", "javascript", "jinja2", "typescript", "yaml", "dockerfile", "shell", "r", "sql", "sql-msSQL", "sql-mySQL", "sql-mariaDB", "sql-sqlite", "sql-cassandra", "sql-plSQL", "sql-hive", "sql-pgSQL", "sql-gql", "sql-gpSQL", "sql-sparkSQL", "sql-esper"
]
language_dropdown = gr.Dropdown(
choices=language_choices,
value="html",
label="Code Language",
visible=True # Always visible
)
website_url_input = gr.Textbox(
label="Website URL for redesign",
placeholder="https://example.com",
lines=1,
visible=True # Always visible
)
file_input = gr.File(
label="Reference file",
file_types=[".pdf", ".txt", ".md", ".csv", ".docx", ".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".gif", ".webp"],
visible=True # Always visible
)
image_input = gr.Image(
label="UI design image",
visible=False # Hidden by default; shown only for ERNIE-VL or GLM-VL
)
with gr.Row():
btn = gr.Button("Generate", variant="primary", size="lg", scale=2, visible=True) # Always visible
clear_btn = gr.Button("Clear", variant="secondary", size="sm", scale=1, visible=True) # Always visible
search_toggle = gr.Checkbox(
label="πŸ” Web search",
value=False,
visible=True # Always visible
)
model_dropdown = gr.Dropdown(
choices=[model['name'] for model in AVAILABLE_MODELS],
value=AVAILABLE_MODELS[0]['name'], # Moonshot Kimi-K2
label="Model",
visible=True # Always visible
)
gr.Markdown("**Quick start**", visible=True)
with gr.Column(visible=True) as quick_examples_col:
for i, demo_item in enumerate(DEMO_LIST[:3]):
demo_card = gr.Button(
value=demo_item['title'],
variant="secondary",
size="sm"
)
demo_card.click(
fn=lambda idx=i: gr.update(value=DEMO_LIST[idx]['description']),
outputs=input
)
if not tavily_client:
gr.Markdown("⚠️ Web search unavailable", visible=True)
else:
gr.Markdown("βœ… Web search available", visible=True)
model_display = gr.Markdown(f"**Model:** {AVAILABLE_MODELS[0]['name']}", visible=True) # Moonshot Kimi-K2
def on_model_change(model_name):
for m in AVAILABLE_MODELS:
if m['name'] == model_name:
return m, f"**Model:** {m['name']}", update_image_input_visibility(m)
return AVAILABLE_MODELS[0], f"**Model:** {AVAILABLE_MODELS[0]['name']}", update_image_input_visibility(AVAILABLE_MODELS[0]) # Moonshot Kimi-K2 fallback
def save_prompt(input):
return {setting: {"system": input}}
model_dropdown.change(
on_model_change,
inputs=model_dropdown,
outputs=[current_model, model_display, image_input]
)
with gr.Accordion("Advanced", open=False, visible=True) as advanced_accordion:
systemPromptInput = gr.Textbox(
value=HTML_SYSTEM_PROMPT,
label="System prompt",
lines=5
)
save_prompt_btn = gr.Button("Save", variant="primary", size="sm")
save_prompt_btn.click(save_prompt, inputs=systemPromptInput, outputs=setting)
with gr.Column():
with gr.Tabs():
with gr.Tab("Code"):
code_output = gr.Code(
language="html",
lines=25,
interactive=False,
label="Generated code"
)
with gr.Tab("Preview"):
sandbox = gr.HTML(label="Live preview")
with gr.Tab("History"):
history_output = gr.Chatbot(show_label=False, height=400, type="messages")
# Event handlers
def update_code_language(language):
return gr.update(language=get_gradio_language(language))
language_dropdown.change(update_code_language, inputs=language_dropdown, outputs=code_output)
def preview_logic(code, language):
if language == "html":
return send_to_sandbox(code)
else:
return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>"
btn.click(
generation_code,
inputs=[input, image_input, file_input, website_url_input, setting, history, current_model, search_toggle, language_dropdown],
outputs=[code_output, history, sandbox, history_output]
)
# Update preview when code or language changes
code_output.change(preview_logic, inputs=[code_output, language_dropdown], outputs=sandbox)
language_dropdown.change(preview_logic, inputs=[code_output, language_dropdown], outputs=sandbox)
clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
if __name__ == "__main__":
demo.queue(api_open=False, default_concurrency_limit=20).launch(ssr_mode=True, mcp_server=False, show_api=False)