import os import uuid import base64 import tempfile from typing import Dict, List, Optional, Tuple import gradio as gr # Import from our modularized files from config import ( AVAILABLE_MODELS, DEFAULT_MODEL, THEME_CONFIGS, DEMO_LIST, HTML_SYSTEM_PROMPT, get_saved_theme, save_theme_preference ) from utils import ( get_inference_client, remove_code_block, extract_text_from_file, create_multimodal_message, apply_search_replace_changes, cleanup_all_temp_media, reap_old_media, get_gradio_language ) from web_utils import extract_website_content, enhance_query_with_search from media_generation import ( generate_image_with_qwen, generate_image_to_image, generate_video_from_image, generate_video_from_text, generate_music_from_text ) from code_processing import ( is_streamlit_code, is_gradio_code, extract_html_document, parse_transformers_js_output, format_transformers_js_output, build_transformers_inline_html, parse_svelte_output, format_svelte_output, parse_multipage_html_output, format_multipage_output, validate_and_autofix_files, inline_multipage_into_single_preview, apply_generated_media_to_html ) from sandbox import send_to_sandbox, send_streamlit_to_stlite, send_gradio_to_lite from generation_engine import generation_code # Initialize theme current_theme_name = get_saved_theme() current_theme = THEME_CONFIGS[current_theme_name]["theme"] # ============================================================================= # PROFESSIONAL UI FUNCTIONS # ============================================================================= def get_model_info_html(model): """Generate HTML for model information""" vision_badge = '👁️ Vision' if model.get('supports_vision') else '' category_color = { 'General': '#3b82f6', 'Code Specialist': '#10b981', 'Vision-Language': '#f59e0b', 'Premium': '#8b5cf6' }.get(model.get('category', 'General'), '#6b7280') return f"""
{model['name']}
{model.get('category', 'General')}
{model.get('description', '')}
{vision_badge} 🚀 Latest
""" def generate_code_stats(code, language): """Generate code statistics HTML""" if not code: return "
No code generated
" try: lines = len(code.split('\n')) chars = len(code) words = len(code.split()) # Language-specific analysis if language == "html": tags = len([m for m in code.split('<') if m.strip()]) stats_content = f"""
{lines} Lines
{tags} HTML Tags
{chars} Characters
{round(chars/1024, 1)}KB Size
""" else: stats_content = f"""
{lines} Lines
{words} Words
{chars} Characters
{language.upper()} Language
""" return f"
{stats_content}
" except Exception: return "
Unable to analyze code
" def handle_model_change(model_selection): """Handle model selection change""" try: # Extract model name from selection model_name = model_selection.split(" (")[0] # Find the model selected_model = None for model in AVAILABLE_MODELS: if model['name'] == model_name: selected_model = model break if selected_model: model_info_html = get_model_info_html(selected_model) return selected_model, model_info_html return DEFAULT_MODEL, get_model_info_html(DEFAULT_MODEL) except Exception: return DEFAULT_MODEL, get_model_info_html(DEFAULT_MODEL) def update_image_input_visibility(model): """Update image input visibility based on selected model""" return gr.update(visible=model.get('supports_vision', False)) def clear_history(): """Clear all inputs and history""" return [], [], None, "", "" def demo_card_click(demo_index): """Handle demo card click""" if 0 <= demo_index < len(DEMO_LIST): return DEMO_LIST[demo_index]['description'] return "" # ============================================================================= # CUSTOM CSS # ============================================================================= CUSTOM_CSS = """ /* Modern Professional Styling */ .gradio-container { max-width: none !important; padding: 0 !important; font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; } .app-header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 24px; border-radius: 0 0 16px 16px; margin-bottom: 24px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); } .header-content { display: flex; justify-content: space-between; align-items: center; max-width: 1400px; margin: 0 auto; } .logo-section { display: flex; align-items: center; gap: 16px; } .logo { font-size: 2.5rem; font-weight: bold; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } .app-title h1 { font-size: 2.2rem; margin: 0; font-weight: 700; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); } .app-title p { margin: 8px 0 0 0; opacity: 0.9; font-size: 1.1rem; font-weight: 300; } .status-indicators { display: flex; flex-direction: column; gap: 12px; } .status-item { display: flex; align-items: center; gap: 10px; font-size: 0.95rem; font-weight: 500; } .status-dot { width: 10px; height: 10px; border-radius: 50%; background: #10b981; box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.3); } .status-dot.active { animation: pulse 2s infinite; } @keyframes pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.7; transform: scale(1.1); } } .sidebar { background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); padding: 24px; border-radius: 16px; border: 1px solid #e2e8f0; height: fit-content; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); } .main-content { padding-left: 24px; } .control-group { margin-bottom: 20px; background: white; padding: 20px; border-radius: 12px; border: 1px solid #e5e7eb; box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.05); } .group-title { font-weight: 600; font-size: 1rem; color: #1f2937; margin-bottom: 16px; display: flex; align-items: center; gap: 8px; border-bottom: 2px solid #f3f4f6; padding-bottom: 8px; } .quick-start-btn { width: 100%; margin-bottom: 8px; text-align: left; justify-content: flex-start; transition: all 0.2s ease; border-radius: 8px; } .quick-start-btn:hover { transform: translateX(4px); background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%); } .input-group { background: white; padding: 28px; border-radius: 16px; border: 1px solid #e2e8f0; margin-bottom: 24px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); } .main-input textarea { font-size: 16px !important; line-height: 1.6 !important; border-radius: 12px !important; border: 2px solid #e5e7eb !important; transition: border-color 0.2s ease !important; } .main-input textarea:focus { border-color: #3b82f6 !important; box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1) !important; } .generate-btn { background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important; border: none !important; font-weight: 600 !important; font-size: 1.1rem !important; padding: 18px 36px !important; border-radius: 12px !important; transition: all 0.3s ease !important; } .generate-btn:hover { transform: translateY(-2px) !important; box-shadow: 0 12px 28px rgba(16, 185, 129, 0.35) !important; background: linear-gradient(135deg, #059669 0%, #047857 100%) !important; } .output-tabs { background: white; border-radius: 16px; overflow: hidden; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05); border: 1px solid #e5e7eb; } .preview-container iframe { border-radius: 12px; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); border: 1px solid #e5e7eb; } .code-editor { border-radius: 12px !important; border: 1px solid #e2e8f0 !important; background: #fafafa !important; } .code-sidebar { padding-left: 20px; } .code-stats { background: white; padding: 20px; border-radius: 12px; border: 1px solid #e5e7eb; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } .stats-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .stat-item { text-align: center; padding: 12px; background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%); border-radius: 8px; border: 1px solid #e5e7eb; } .stat-number { display: block; font-size: 1.5rem; font-weight: 700; color: #1f2937; margin-bottom: 4px; } .stat-label { font-size: 0.75rem; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 500; } .model-info { background: white; padding: 16px; border-radius: 10px; border: 1px solid #e5e7eb; margin-top: 12px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); } .model-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; } .model-name { font-weight: 600; color: #1f2937; font-size: 1rem; } .category-badge { padding: 4px 12px; border-radius: 16px; font-size: 0.75rem; font-weight: 600; color: white; text-transform: uppercase; letter-spacing: 0.05em; } .model-description { font-size: 0.9rem; color: #6b7280; margin-bottom: 12px; line-height: 1.5; } .model-features { display: flex; gap: 6px; flex-wrap: wrap; } .feature-badge { padding: 3px 8px; border-radius: 10px; font-size: 0.7rem; font-weight: 500; background: #f3f4f6; color: #374151; } .feature-badge.vision { background: #fef3c7; color: #92400e; } .preview-message { text-align: center; padding: 60px 24px; color: #6b7280; background: linear-gradient(135deg, #f9fafb 0%, #f3f4f6 100%); border-radius: 12px; border: 2px dashed #d1d5db; font-size: 1.1rem; font-weight: 500; } .error-message { text-align: center; padding: 24px; color: #dc2626; background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%); border: 1px solid #fecaca; border-radius: 12px; font-weight: 500; } .preview-controls { background: #f8fafc; padding: 12px 20px; border-radius: 8px 8px 0 0; border-bottom: 1px solid #e5e7eb; } .preview-info { display: flex; justify-content: center; gap: 24px; font-size: 0.85rem; color: #6b7280; } .info-item { display: flex; align-items: center; gap: 6px; } /* Responsive design */ @media (max-width: 768px) { .header-content { flex-direction: column; gap: 20px; text-align: center; } .stats-grid { grid-template-columns: 1fr; } .main-content { padding-left: 0; margin-top: 24px; } .status-indicators { flex-direction: row; justify-content: center; } } /* Animation improvements */ .control-group { transition: transform 0.2s ease, box-shadow 0.2s ease; } .control-group:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); } """ # ============================================================================= # MAIN APPLICATION # ============================================================================= def create_professional_ui(): """Create the professional AnyCoder UI""" with gr.Blocks( title="AnyCoder - Professional AI Development Suite", theme=current_theme, css=CUSTOM_CSS, head=""" """ ) as demo: # State management history = gr.State([]) setting = gr.State({"system": HTML_SYSTEM_PROMPT}) current_model = gr.State(DEFAULT_MODEL) session_state = gr.State({"session_id": str(uuid.uuid4())}) # Header with gr.Row(elem_classes=["header-row"]): with gr.Column(scale=3): gr.HTML("""

AnyCoder

Professional AI Development Suite

AI Models Ready
Media Generation Active
""") with gr.Column(scale=1, min_width=200): with gr.Row(): login_button = gr.LoginButton(scale=1, size="sm") # Main interface with gr.Row(): # Left sidebar - Controls with gr.Column(scale=1, elem_classes=["sidebar"]): # Model Selection with gr.Group(elem_classes=["control-group"]): gr.HTML('
🤖 AI Model
') model_dropdown = gr.Dropdown( choices=[f"{model['name']} ({model['category']})" for model in AVAILABLE_MODELS], value=f"{DEFAULT_MODEL['name']} ({DEFAULT_MODEL['category']})", label="Select Model", container=False ) model_info = gr.HTML(get_model_info_html(DEFAULT_MODEL)) # Project Configuration with gr.Group(elem_classes=["control-group"]): gr.HTML('
⚙️ Project Settings
') language_dropdown = gr.Dropdown( choices=[ "html", "streamlit", "gradio", "python", "transformers.js", "svelte", "javascript", "css" ], value="html", label="Project Type", container=False ) search_toggle = gr.Checkbox( label="🔍 Enable Web Search", value=False, info="Include web search for current information", container=False ) # Media Generation Controls with gr.Group(elem_classes=["control-group"]): gr.HTML('
🎨 Media Generation
') enable_images = gr.Checkbox( label="Generate Images (text → image)", value=False, container=False ) enable_image_to_image = gr.Checkbox( label="Transform Images (image → image)", value=False, container=False ) enable_video = gr.Checkbox( label="Generate Videos (text → video)", value=False, container=False ) enable_music = gr.Checkbox( label="Generate Music (text → music)", value=False, container=False ) # Input Sources with gr.Group(elem_classes=["control-group"]): gr.HTML('
📁 Input Sources
') file_input = gr.File( label="Reference File", file_types=[".pdf", ".txt", ".md", ".csv", ".docx", ".jpg", ".jpeg", ".png"], container=False ) website_url_input = gr.Textbox( label="Website URL (for redesign)", placeholder="https://example.com", container=False ) image_input = gr.Image( label="Design Reference Image", visible=DEFAULT_MODEL.get('supports_vision', False), container=False ) # Quick Start Examples with gr.Group(elem_classes=["control-group"]): gr.HTML('
🚀 Quick Start
') quick_start_buttons = [] for i, demo in enumerate(DEMO_LIST): btn = gr.Button( demo["title"], variant="secondary", size="sm", elem_classes=["quick-start-btn"] ) quick_start_buttons.append(btn) # Main content area with gr.Column(scale=3, elem_classes=["main-content"]): # Input area with gr.Group(elem_classes=["input-group"]): input_textbox = gr.Textbox( label="What would you like to build?", placeholder="Describe your application in detail... (e.g., 'Create a modern dashboard with charts and user management')", lines=4, container=False, elem_classes=["main-input"] ) with gr.Row(): generate_btn = gr.Button( "🚀 Generate Application", variant="primary", scale=3, size="lg", elem_classes=["generate-btn"] ) clear_btn = gr.Button( "🗑️ Clear", variant="secondary", scale=1, size="lg" ) # Output area with professional tabs with gr.Tabs(elem_classes=["output-tabs"]): # Preview Tab with gr.Tab("🖥️ Live Preview"): preview_controls = gr.HTML("""
📱 Responsive Design ⚡ Real-time Updates 🔒 Sandboxed Environment
""") sandbox = gr.HTML( "
Ready to generate your application
", elem_classes=["preview-container"] ) # Code Tab with gr.Tab("💻 Source Code"): with gr.Row(): with gr.Column(scale=4): code_output = gr.Code( language="html", lines=25, interactive=True, label="Generated Code", elem_classes=["code-editor"] ) with gr.Column(scale=1, elem_classes=["code-sidebar"]): # Code stats with gr.Group(): gr.HTML('
📊 Code Statistics
') code_stats = gr.HTML( "
Ready to generate...
", elem_classes=["code-stats"] ) # Hidden components for functionality history_output = gr.Chatbot(show_label=False, height=400, type="messages", visible=False) # ============================================================================= # EVENT HANDLERS # ============================================================================= # Model selection handler model_dropdown.change( handle_model_change, inputs=[model_dropdown], outputs=[current_model, model_info] ) # Update image input visibility based on model current_model.change( update_image_input_visibility, inputs=[current_model], outputs=[image_input] ) # Generation handler generate_btn.click( generation_code, inputs=[ input_textbox, image_input, gr.State(None), # generation_image_input placeholder file_input, website_url_input, setting, history, current_model, search_toggle, language_dropdown, gr.State("auto"), # provider_state enable_images, enable_image_to_image, gr.State(""), # image_to_image_prompt placeholder gr.State(""), # text_to_image_prompt placeholder gr.State(False), # enable_image_to_video placeholder gr.State(""), # image_to_video_prompt placeholder enable_video, gr.State(""), # text_to_video_prompt placeholder enable_music, gr.State("") # text_to_music_prompt placeholder ], outputs=[code_output, history, sandbox, history_output] ).then( generate_code_stats, inputs=[code_output, language_dropdown], outputs=[code_stats] ) # Enter key in input triggers generation input_textbox.submit( generation_code, inputs=[ input_textbox, image_input, gr.State(None), file_input, website_url_input, setting, history, current_model, search_toggle, language_dropdown, gr.State("auto"), enable_images, enable_image_to_image, gr.State(""), gr.State(""), gr.State(False), gr.State(""), enable_video, gr.State(""), enable_music, gr.State("") ], outputs=[code_output, history, sandbox, history_output] ).then( generate_code_stats, inputs=[code_output, language_dropdown], outputs=[code_stats] ) # Clear handler clear_btn.click( clear_history, outputs=[history, history_output, file_input, website_url_input, input_textbox] ).then( lambda: [ gr.update(value="", language="html"), "
Ready to generate your next application
", "
Ready to generate...
" ], outputs=[code_output, sandbox, code_stats] ) # Quick start button handlers for i, btn in enumerate(quick_start_buttons): if i < len(DEMO_LIST): btn.click( lambda demo_idx=i: DEMO_LIST[demo_idx]['description'], outputs=[input_textbox] ) # Language change updates code editor language_dropdown.change( lambda lang: gr.update(language=get_gradio_language(lang)), inputs=[language_dropdown], outputs=[code_output] ) return demo # ============================================================================= # MAIN ENTRY POINT # ============================================================================= def main(): """Main application entry point""" print("🚀 Starting AnyCoder Professional AI Development Suite...") # Setup cleanup cleanup_all_temp_media() reap_old_media() # Create and launch the UI demo = create_professional_ui() demo.queue(api_open=False, default_concurrency_limit=20).launch( show_api=False, share=False, server_name="0.0.0.0", server_port=7860, show_error=True ) if __name__ == "__main__": main()