yeye / app.py
mgbam's picture
Update app.py
603166e verified
raw
history blame
46.5 kB
import os
import uuid
import base64
import tempfile
from typing import Dict, List, Optional, Tuple, Union
import gradio as gr
# Import all our modules
from config import (
AVAILABLE_MODELS, DEFAULT_MODEL, THEME_CONFIGS, DEMO_LIST,
HTML_SYSTEM_PROMPT, get_saved_theme, save_theme_preference, get_gradio_language
)
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, process_image_for_model
)
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
)
# Initialize theme
current_theme_name = get_saved_theme()
current_theme = THEME_CONFIGS[current_theme_name]["theme"]
class AnyCoder:
"""Main AnyCoder application class"""
def __init__(self):
self.setup_cleanup()
def setup_cleanup(self):
"""Setup cleanup handlers"""
cleanup_all_temp_media()
reap_old_media()
def create_advanced_ui(self):
"""Create the advanced professional UI"""
with gr.Blocks(
title="AnyCoder - Professional AI Development Suite",
theme=current_theme,
css=self.get_custom_css(),
head=self.get_head_html()
) as app:
# State management
history = gr.State([])
setting = gr.State({"system": HTML_SYSTEM_PROMPT})
current_model = gr.State(DEFAULT_MODEL)
session_state = gr.State({})
# Header
with gr.Row(elem_classes=["header-row"]):
with gr.Column(scale=3):
gr.HTML("""
<div class="app-header">
<div class="header-content">
<div class="logo-section">
<div class="logo">⚑</div>
<div class="app-title">
<h1>AnyCoder</h1>
<p>Professional AI Development Suite</p>
</div>
</div>
<div class="status-indicators">
<div class="status-item">
<span class="status-dot active"></span>
<span>AI Models Ready</span>
</div>
<div class="status-item">
<span class="status-dot active"></span>
<span>Web Search Available</span>
</div>
</div>
</div>
</div>
""")
with gr.Column(scale=1, min_width=200):
with gr.Row():
login_button = gr.LoginButton(scale=1, size="sm")
theme_selector = gr.Dropdown(
choices=list(THEME_CONFIGS.keys()),
value=current_theme_name,
label="Theme",
scale=1,
container=False
)
# Main interface
with gr.Row():
# Left sidebar - Controls
with gr.Column(scale=1, elem_classes=["sidebar"]):
self.create_sidebar(current_model, session_state)
# Main content area
with gr.Column(scale=3, elem_classes=["main-content"]):
self.create_main_content(history, current_model)
# Connect all the event handlers
self.setup_event_handlers(app, history, setting, current_model, session_state)
return app
def create_sidebar(self, current_model, session_state):
"""Create the professional sidebar"""
# Model Selection
with gr.Group(elem_classes=["control-group"]):
gr.HTML('<div class="group-title">πŸ€– AI Model</div>')
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 display
model_info = gr.HTML(self.get_model_info_html(DEFAULT_MODEL))
# Web Search Toggle
with gr.Group(elem_classes=["control-group"]):
search_toggle = gr.Checkbox(
label="πŸ” Web search",
value=False,
info="Include generated images in your outputs using Qwen image model",
container=False
)
# Media Generation Controls
with gr.Group(elem_classes=["control-group"]):
gr.HTML('<div class="group-title">🎨 Media Generation</div>')
enable_images = gr.Checkbox(
label="πŸ–ΌοΈ Generate Images (text β†’ image)",
value=False,
info="Include generated images in your outputs using Qwen image model",
container=False
)
enable_image_to_image = gr.Checkbox(
label="πŸ–ΌοΈ Image to Image (uses input image)",
value=False,
info="Transform your uploaded image using Qwen image/edit",
container=False
)
enable_image_to_video = gr.Checkbox(
label="🎬 Image to Video (uses input image)",
value=False,
info="Generate a short video from your uploaded image using Lightricks LTX-Video",
container=False
)
enable_text_to_video = gr.Checkbox(
label="🎬 Generate Video (text β†’ video)",
value=False,
info="Generate a short video directly from your prompt using WanAi/Wan2.2-TIZV-S8",
container=False
)
enable_music = gr.Checkbox(
label="🎡 Generate Music (text β†’ music)",
value=False,
info="Compose short music from your prompt using ElevenLabs Music",
container=False
)
# Model Information
with gr.Group(elem_classes=["control-group"]):
model_display = gr.HTML(
'<div class="model-name">Qwen3-Coder-4800-A535-Instruc</div>',
elem_classes=["model-display"]
)
# Quick Start Examples
with gr.Group(elem_classes=["control-group"]):
gr.HTML('<div class="group-title">πŸš€ Quick Start</div>')
# Create buttons for each demo instead of gallery
quick_start_buttons = []
for demo in DEMO_LIST[:6]:
btn = gr.Button(
demo["title"],
variant="secondary",
size="sm",
elem_classes=["quick-start-btn"]
)
quick_start_buttons.append(btn)
# Project Configuration
with gr.Group(elem_classes=["control-group"]):
gr.HTML('<div class="group-title">βš™οΈ Project Settings</div>')
language_dropdown = gr.Dropdown(
choices=[
("Static HTML", "html"),
("Streamlit App", "streamlit"),
("Gradio App", "gradio"),
("Transformers.js", "transformers.js"),
("Svelte App", "svelte"),
("Python Script", "python"),
("JavaScript", "javascript"),
("CSS Styles", "css"),
("Other", "other")
],
value="html",
label="Project Type",
container=False
)
advanced_mode = gr.Checkbox(
label="Advanced Mode",
value=False,
info="Show advanced options",
container=False
)
# Input Sources
with gr.Group(elem_classes=["control-group"]):
gr.HTML('<div class="group-title">πŸ“ Input Sources</div>')
file_input = gr.File(
label="Upload 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",
container=False
)
# Advanced Controls (initially hidden)
with gr.Group(elem_classes=["control-group"], visible=False) as advanced_controls:
gr.HTML('<div class="group-title">πŸ”§ Advanced Options</div>')
media_prompts = gr.Textbox(
label="Media Generation Prompts",
placeholder="Describe media to generate...",
lines=2,
container=False
)
# Project Import
with gr.Group(elem_classes=["control-group"]):
gr.HTML('<div class="group-title">πŸ“₯ Import Project</div>')
import_url = gr.Textbox(
label="GitHub/HuggingFace URL",
placeholder="https://github.com/user/repo or https://huggingface.co/spaces/user/space",
container=False
)
with gr.Row():
import_btn = gr.Button("Import", variant="secondary", size="sm")
import_status = gr.HTML("", visible=False)
# Store sidebar components for event handling
self.sidebar_components = {
'model_dropdown': model_dropdown,
'model_info': model_info,
'model_display': model_display,
'language_dropdown': language_dropdown,
'search_toggle': search_toggle,
'advanced_mode': advanced_mode,
'file_input': file_input,
'website_url_input': website_url_input,
'image_input': image_input,
'advanced_controls': advanced_controls,
'enable_images': enable_images,
'enable_image_to_image': enable_image_to_image,
'enable_image_to_video': enable_image_to_video,
'enable_text_to_video': enable_text_to_video,
'enable_music': enable_music,
'media_prompts': media_prompts,
'quick_start_buttons': quick_start_buttons,
'import_url': import_url,
'import_btn': import_btn,
'import_status': import_status
}
# Setup sidebar event handlers
self.setup_sidebar_events(session_state)
def setup_sidebar_events(self, session_state):
"""Setup sidebar-specific event handlers"""
# Show advanced controls when enabled
self.sidebar_components['advanced_mode'].change(
lambda checked: gr.update(visible=checked),
inputs=[self.sidebar_components['advanced_mode']],
outputs=[self.sidebar_components['advanced_controls']]
)
# Show media prompts when any media generation is enabled
media_checkboxes = [
self.sidebar_components['enable_images'],
self.sidebar_components['enable_image_to_image'],
self.sidebar_components['enable_image_to_video'],
self.sidebar_components['enable_text_to_video'],
self.sidebar_components['enable_music']
]
for checkbox in media_checkboxes:
checkbox.change(
lambda *args: gr.update(visible=any(args)),
inputs=media_checkboxes,
outputs=[self.sidebar_components['media_prompts']]
)
# Update session state when media options change
for i, checkbox in enumerate(media_checkboxes):
checkbox.change(
self.update_media_settings,
inputs=[checkbox],
outputs=[session_state]
)
def update_media_settings(self, *checkbox_values):
"""Update media generation settings in session state"""
settings = {
'enable_images': checkbox_values[0] if len(checkbox_values) > 0 else False,
'enable_image_to_image': checkbox_values[1] if len(checkbox_values) > 1 else False,
'enable_image_to_video': checkbox_values[2] if len(checkbox_values) > 2 else False,
'enable_text_to_video': checkbox_values[3] if len(checkbox_values) > 3 else False,
'enable_music': checkbox_values[4] if len(checkbox_values) > 4 else False
}
return settings
def create_main_content(self, history, current_model):
"""Create the main content area"""
# 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", elem_classes=["preview-tab"]):
with gr.Group():
preview_controls = gr.HTML("""
<div class="preview-controls">
<div class="preview-info">
<span class="info-item">πŸ“± Responsive Design</span>
<span class="info-item">⚑ Real-time Updates</span>
<span class="info-item">πŸ”’ Sandboxed Environment</span>
</div>
</div>
""")
sandbox = gr.HTML(
label="Application Preview",
elem_classes=["preview-container"]
)
# Code Tab
with gr.Tab("πŸ’» Source Code", elem_classes=["code-tab"]):
with gr.Row():
with gr.Column(scale=4):
code_output = gr.Code(
language="html",
lines=30,
interactive=True,
label="Generated Code",
elem_classes=["code-editor"]
)
with gr.Column(scale=1, elem_classes=["code-sidebar"]):
# Code actions
with gr.Group():
gr.HTML('<div class="group-title">πŸ”§ Code Actions</div>')
copy_btn = gr.Button("πŸ“‹ Copy Code", size="sm")
download_btn = gr.Button("πŸ’Ύ Download", size="sm")
format_btn = gr.Button("✨ Format", size="sm")
# Code stats
with gr.Group():
gr.HTML('<div class="group-title">πŸ“Š Code Stats</div>')
code_stats = gr.HTML(
'<div class="code-stats">Ready to generate...</div>',
elem_classes=["code-stats"]
)
# Deployment Tab
with gr.Tab("πŸš€ Deploy", elem_classes=["deploy-tab"]):
with gr.Row():
with gr.Column(scale=2):
with gr.Group():
gr.HTML('<div class="group-title">🌐 Deployment Options</div>')
deploy_platform = gr.Dropdown(
choices=[
("Hugging Face Spaces", "hf_spaces"),
("Vercel", "vercel"),
("Netlify", "netlify"),
("GitHub Pages", "github_pages")
],
value="hf_spaces",
label="Platform",
container=False
)
app_name = gr.Textbox(
label="Application Name",
placeholder="my-awesome-app",
container=False
)
deploy_btn = gr.Button(
"πŸš€ Deploy Now",
variant="primary",
size="lg"
)
with gr.Column(scale=1):
deployment_status = gr.HTML(
'<div class="deployment-status">Ready to deploy</div>',
elem_classes=["deployment-status"]
)
# Generation status
generation_status = gr.HTML(
visible=False,
elem_classes=["generation-status"]
)
# Store main content components
self.main_components = {
'input_textbox': input_textbox,
'generate_btn': generate_btn,
'clear_btn': clear_btn,
'sandbox': sandbox,
'code_output': code_output,
'code_stats': code_stats,
'copy_btn': copy_btn,
'download_btn': download_btn,
'format_btn': format_btn,
'deploy_platform': deploy_platform,
'app_name': app_name,
'deploy_btn': deploy_btn,
'deployment_status': deployment_status,
'generation_status': generation_status
}
def setup_event_handlers(self, app, history, setting, current_model, session_state):
"""Setup all event handlers for the application"""
# Generation handler
self.main_components['generate_btn'].click(
self.handle_generation,
inputs=[
self.main_components['input_textbox'],
self.sidebar_components['file_input'],
self.sidebar_components['website_url_input'],
self.sidebar_components['image_input'],
self.sidebar_components['language_dropdown'],
self.sidebar_components['search_toggle'],
current_model,
history,
session_state
],
outputs=[
self.main_components['code_output'],
self.main_components['sandbox'],
self.main_components['code_stats'],
history
]
)
# Model selection handler
self.sidebar_components['model_dropdown'].change(
self.handle_model_change,
inputs=[self.sidebar_components['model_dropdown']],
outputs=[current_model, self.sidebar_components['model_info']]
)
# Clear handler
self.main_components['clear_btn'].click(
self.handle_clear,
outputs=[
self.main_components['input_textbox'],
self.main_components['code_output'],
self.main_components['sandbox'],
self.main_components['code_stats'],
history
]
)
# Quick start button handlers
for i, btn in enumerate(self.sidebar_components['quick_start_buttons']):
if i < len(DEMO_LIST):
btn.click(
lambda demo_idx=i: DEMO_LIST[demo_idx]['description'],
outputs=[self.main_components['input_textbox']]
)
def handle_generation(self, prompt, file, website_url, image, language,
enable_search, current_model_state, history_state, session_state):
"""Handle code generation with advanced features"""
if not prompt.strip():
return (
gr.update(),
"<div class='error-message'>Please enter a description of what you'd like to build.</div>",
"<div class='code-stats error'>No input provided</div>",
history_state
)
try:
# Setup session
session_id = session_state.get('session_id', str(uuid.uuid4()))
session_state['session_id'] = session_id
# Enhance prompt with file content
enhanced_prompt = prompt
if file:
file_content = extract_text_from_file(file.name)
if file_content:
enhanced_prompt = f"{prompt}\n\n[Reference file content]\n{file_content[:5000]}"
# Enhance with website content
if website_url and website_url.strip():
website_content = extract_website_content(website_url.strip())
if website_content and not website_content.startswith("Error"):
enhanced_prompt = f"{enhanced_prompt}\n\n[Website content to redesign]\n{website_content[:8000]}"
# Enhance with web search if enabled
if enable_search:
enhanced_prompt = enhance_query_with_search(enhanced_prompt, True)
# Generate code using selected model
generated_code = self.generate_code_with_model(
enhanced_prompt, current_model_state, language, image
)
# Process the generated code
processed_code = remove_code_block(generated_code)
# Apply media generation if enabled
if any([
session_state.get('enable_images', False),
session_state.get('enable_image_to_image', False),
session_state.get('enable_image_to_video', False),
session_state.get('enable_text_to_video', False),
session_state.get('enable_music', False)
]):
processed_code = apply_generated_media_to_html(
processed_code,
prompt,
enable_text_to_image=session_state.get('enable_images', False),
enable_image_to_image=session_state.get('enable_image_to_image', False),
enable_image_to_video=session_state.get('enable_image_to_video', False),
enable_text_to_video=session_state.get('enable_text_to_video', False),
enable_text_to_music=session_state.get('enable_music', False),
session_id=session_id
)
# Generate preview
preview_html = self.generate_preview(processed_code, language)
# Update code stats
stats_html = self.generate_code_stats(processed_code, language)
# Update history
history_state.append([prompt, processed_code])
return (
gr.update(value=processed_code, language=get_gradio_language(language)),
preview_html,
stats_html,
history_state
)
except Exception as e:
error_html = f"<div class='error-message'>Generation Error: {str(e)}</div>"
return (
gr.update(value=f"// Error: {str(e)}"),
error_html,
"<div class='code-stats error'>Generation failed</div>",
history_state
)
def generate_code_with_model(self, prompt, model_state, language, image):
"""Generate code using the selected model"""
try:
client = get_inference_client(model_state['id'], "auto")
# Select appropriate system prompt based on language
system_prompts = {
'html': HTML_SYSTEM_PROMPT,
'streamlit': "You are an expert Streamlit developer. Create modern, interactive Streamlit applications with clean code and professional UI.",
'gradio': "You are an expert Gradio developer. Create modern, interactive Gradio applications with clean interfaces and robust functionality.",
'transformers.js': "You are an expert in Transformers.js. Create modern web applications using Transformers.js for AI/ML functionality.",
'svelte': "You are an expert Svelte developer. Create modern, reactive Svelte applications with TypeScript and clean architecture."
}
system_prompt = system_prompts.get(language, HTML_SYSTEM_PROMPT)
# Prepare messages
messages = [
{"role": "system", "content": system_prompt}
]
if image:
messages.append(create_multimodal_message(prompt, image))
else:
messages.append({"role": "user", "content": prompt})
# Generate with streaming for better UX
if hasattr(client, 'chat') and hasattr(client.chat, 'completions'):
completion = client.chat.completions.create(
model=model_state['id'],
messages=messages,
max_tokens=16384,
temperature=0.7,
stream=False # For simplicity in this demo
)
return completion.choices[0].message.content
else:
# Fallback for different client types
return "Generated code would appear here..."
except Exception as e:
raise Exception(f"Model generation failed: {str(e)}")
def generate_preview(self, code, language):
"""Generate HTML preview for the code"""
try:
if language == "html":
# Handle multi-page HTML
files = parse_multipage_html_output(code)
if files and files.get('index.html'):
files = validate_and_autofix_files(files)
preview_code = inline_multipage_into_single_preview(files)
else:
preview_code = extract_html_document(code)
return self.send_to_sandbox(preview_code)
elif language == "transformers.js":
files = parse_transformers_js_output(code)
if files['index.html'] and files['index.js'] and files['style.css']:
merged_html = build_transformers_inline_html(files)
return self.send_to_sandbox(merged_html)
else:
return "<div class='preview-message'>⏳ Generating Transformers.js application...</div>"
elif language == "streamlit":
if is_streamlit_code(code):
return self.send_streamlit_to_stlite(code)
else:
return "<div class='preview-message'>Add <code>import streamlit as st</code> to enable preview</div>"
elif language == "gradio":
if is_gradio_code(code):
return self.send_gradio_to_lite(code)
else:
return "<div class='preview-message'>Add <code>import gradio as gr</code> to enable preview</div>"
else:
return f"<div class='preview-message'>πŸ’» {language.upper()} code generated successfully. Preview not available for this language.</div>"
except Exception as e:
return f"<div class='error-message'>Preview Error: {str(e)}</div>"
def send_to_sandbox(self, html_code):
"""Send HTML to sandboxed iframe"""
if not html_code.strip():
return "<div class='preview-message'>No content to preview</div>"
try:
encoded_html = base64.b64encode(html_code.encode('utf-8')).decode('utf-8')
data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
iframe = f'''
<iframe
src="{data_uri}"
width="100%"
height="800px"
sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals"
style="border: 1px solid #e5e7eb; border-radius: 8px; background: white;"
allow="display-capture">
</iframe>
'''
return iframe
except Exception as e:
return f"<div class='error-message'>Sandbox Error: {str(e)}</div>"
def send_streamlit_to_stlite(self, code):
"""Send Streamlit code to stlite preview"""
html_doc = f"""
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Streamlit Preview</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@stlite/browser@0.86.0/build/stlite.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@stlite/browser@0.86.0/build/stlite.js"></script>
</head>
<body>
<streamlit-app>{code}</streamlit-app>
</body>
</html>
"""
return self.send_to_sandbox(html_doc)
def send_gradio_to_lite(self, code):
"""Send Gradio code to gradio-lite preview"""
html_doc = f"""
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Gradio Preview</title>
<script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.css" />
</head>
<body>
<gradio-lite>{code}</gradio-lite>
</body>
</html>
"""
return self.send_to_sandbox(html_doc)
def generate_code_stats(self, code, language):
"""Generate code statistics"""
if not code:
return "<div class='code-stats'>No code generated</div>"
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"""
<div class='stats-grid'>
<div class='stat-item'>
<span class='stat-number'>{lines}</span>
<span class='stat-label'>Lines</span>
</div>
<div class='stat-item'>
<span class='stat-number'>{tags}</span>
<span class='stat-label'>HTML Tags</span>
</div>
<div class='stat-item'>
<span class='stat-number'>{chars}</span>
<span class='stat-label'>Characters</span>
</div>
<div class='stat-item'>
<span class='stat-number'>{round(chars/1024, 1)}KB</span>
<span class='stat-label'>Size</span>
</div>
</div>
"""
else:
stats_content = f"""
<div class='stats-grid'>
<div class='stat-item'>
<span class='stat-number'>{lines}</span>
<span class='stat-label'>Lines</span>
</div>
<div class='stat-item'>
<span class='stat-number'>{words}</span>
<span class='stat-label'>Words</span>
</div>
<div class='stat-item'>
<span class='stat-number'>{chars}</span>
<span class='stat-label'>Characters</span>
</div>
<div class='stat-item'>
<span class='stat-number'>{language.upper()}</span>
<span class='stat-label'>Language</span>
</div>
</div>
"""
return f"<div class='code-stats'>{stats_content}</div>"
except Exception:
return "<div class='code-stats'>Unable to analyze code</div>"
def handle_model_change(self, 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 = self.get_model_info_html(selected_model)
return selected_model, model_info_html
return DEFAULT_MODEL, self.get_model_info_html(DEFAULT_MODEL)
except Exception:
return DEFAULT_MODEL, self.get_model_info_html(DEFAULT_MODEL)
def handle_clear(self):
"""Handle clear button"""
return (
gr.update(value=""), # input_textbox
gr.update(value="", language="html"), # code_output
"<div class='preview-message'>Ready to generate your next application</div>", # sandbox
"<div class='code-stats'>Ready to generate...</div>", # code_stats
[] # history
)
def get_model_info_html(self, model):
"""Generate HTML for model information"""
vision_badge = '<span class="feature-badge vision">πŸ‘οΈ Vision</span>' 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"""
<div class="model-info">
<div class="model-header">
<div class="model-name">{model['name']}</div>
<span class="category-badge" style="background-color: {category_color}">
{model.get('category', 'General')}
</span>
</div>
<div class="model-description">{model.get('description', '')}</div>
<div class="model-features">
{vision_badge}
<span class="feature-badge">πŸš€ Latest</span>
</div>
</div>
"""
def get_custom_css(self):
"""Get custom CSS for the application"""
return """
/* Modern Professional Styling */
.gradio-container {
max-width: none !important;
padding: 0 !important;
}
.app-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 20px;
border-radius: 0 0 16px 16px;
margin-bottom: 20px;
}
.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: 15px;
}
.logo {
font-size: 2.5rem;
font-weight: bold;
}
.app-title h1 {
font-size: 2rem;
margin: 0;
font-weight: 700;
}
.app-title p {
margin: 5px 0 0 0;
opacity: 0.9;
font-size: 1rem;
}
.status-indicators {
display: flex;
flex-direction: column;
gap: 8px;
}
.status-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 0.9rem;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #10b981;
}
.status-dot.active {
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.5; }
}
.sidebar {
background: #f8fafc;
padding: 20px;
border-radius: 12px;
border: 1px solid #e2e8f0;
height: fit-content;
}
.main-content {
padding-left: 20px;
}
.control-group {
margin-bottom: 16px;
background: white;
padding: 16px;
border-radius: 8px;
border: 1px solid #e5e7eb;
}
.group-title {
font-weight: 600;
font-size: 0.95rem;
color: #374151;
margin-bottom: 12px;
display: flex;
align-items: center;
gap: 8px;
}
.model-display {
background: #f3f4f6;
padding: 8px 12px;
border-radius: 6px;
border: 1px solid #d1d5db;
}
.model-display .model-name {
font-family: 'Monaco', 'Consolas', monospace;
font-size: 0.85rem;
color: #374151;
}
.quick-start-btn {
width: 100%;
margin-bottom: 4px;
text-align: left;
justify-content: flex-start;
}
.input-group {
background: white;
padding: 24px;
border-radius: 12px;
border: 1px solid #e2e8f0;
margin-bottom: 20px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
}
.main-input textarea {
font-size: 16px !important;
line-height: 1.5 !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: 16px 32px !important;
}
.generate-btn:hover {
transform: translateY(-1px);
box-shadow: 0 10px 25px rgba(16, 185, 129, 0.3) !important;
}
.output-tabs .tab-nav {
background: #f8fafc;
border-radius: 8px 8px 0 0;
border-bottom: 1px solid #e2e8f0;
}
.preview-container iframe {
border-radius: 8px;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.code-editor {
border-radius: 8px;
border: 1px solid #e2e8f0;
}
.code-sidebar {
padding-left: 16px;
}
.code-sidebar .control-group {
margin-bottom: 16px;
padding: 12px;
}
.code-stats {
background: white;
padding: 16px;
border-radius: 8px;
border: 1px solid #e5e7eb;
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.stat-item {
text-align: center;
padding: 8px;
background: #f8fafc;
border-radius: 6px;
}
.stat-number {
display: block;
font-size: 1.25rem;
font-weight: 700;
color: #1f2937;
}
.stat-label {
font-size: 0.75rem;
color: #6b7280;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.model-info {
background: white;
padding: 12px;
border-radius: 6px;
border: 1px solid #e5e7eb;
margin-top: 8px;
}
.model-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.model-name {
font-weight: 600;
color: #1f2937;
}
.category-badge {
padding: 2px 8px;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 500;
color: white;
}
.model-description {
font-size: 0.85rem;
color: #6b7280;
margin-bottom: 8px;
}
.model-features {
display: flex;
gap: 4px;
}
.feature-badge {
padding: 2px 6px;
border-radius: 8px;
font-size: 0.7rem;
font-weight: 500;
background: #f3f4f6;
color: #374151;
}
.feature-badge.vision {
background: #fef3c7;
color: #92400e;
}
.preview-message {
text-align: center;
padding: 40px 20px;
color: #6b7280;
background: #f9fafb;
border-radius: 8px;
border: 2px dashed #d1d5db;
}
.error-message {
text-align: center;
padding: 20px;
color: #dc2626;
background: #fef2f2;
border: 1px solid #fecaca;
border-radius: 8px;
}
.deployment-status {
background: white;
padding: 16px;
border-radius: 8px;
border: 1px solid #e5e7eb;
text-align: center;
color: #6b7280;
}
/* 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: 20px;
}
}
"""
def get_head_html(self):
"""Get additional head HTML"""
return """
<meta name="description" content="AnyCoder - Professional AI Development Suite for creating modern applications">
<meta name="keywords" content="AI, code generation, web development, automation">
<meta name="author" content="AnyCoder">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<style>
body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
</style>
"""
def main():
"""Main application entry point"""
print("πŸš€ Starting AnyCoder Professional AI Development Suite...")
# Initialize the application
app_instance = AnyCoder()
demo = app_instance.create_advanced_ui()
# Launch with optimal settings
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,
quiet=False
)
if __name__ == "__main__":
main()