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, ) from file_processing import create_multimodal_message from web_extraction import enhance_query_with_search 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 "
Preview is only available for HTML. Please download your code using the download button above.
" 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)