mgbam commited on
Commit
a11e7ef
·
verified ·
1 Parent(s): 44196e5

Rename app.py to app..py

Browse files
Files changed (2) hide show
  1. app..py +1166 -0
  2. app.py +0 -848
app..py ADDED
@@ -0,0 +1,1166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Main AnyCoder application with advanced professional UI.
3
+ """
4
+
5
+ import os
6
+ import uuid
7
+ import base64
8
+ import tempfile
9
+ from typing import Dict, List, Optional, Tuple, Union
10
+
11
+ import gradio as gr
12
+
13
+ # Import all our modules
14
+ from config import (
15
+ AVAILABLE_MODELS, DEFAULT_MODEL, THEME_CONFIGS, DEMO_LIST,
16
+ HTML_SYSTEM_PROMPT, get_saved_theme, save_theme_preference, get_gradio_language
17
+ )
18
+ from utils import (
19
+ get_inference_client, remove_code_block, extract_text_from_file,
20
+ create_multimodal_message, apply_search_replace_changes,
21
+ cleanup_all_temp_media, reap_old_media, process_image_for_model
22
+ )
23
+ from web_utils import extract_website_content, enhance_query_with_search
24
+ from media_generation import (
25
+ generate_image_with_qwen, generate_image_to_image, generate_video_from_image,
26
+ generate_video_from_text, generate_music_from_text
27
+ )
28
+ from code_processing import (
29
+ is_streamlit_code, is_gradio_code, extract_html_document,
30
+ parse_transformers_js_output, format_transformers_js_output, build_transformers_inline_html,
31
+ parse_svelte_output, format_svelte_output,
32
+ parse_multipage_html_output, format_multipage_output,
33
+ validate_and_autofix_files, inline_multipage_into_single_preview,
34
+ apply_generated_media_to_html
35
+ )
36
+
37
+ # Initialize theme
38
+ current_theme_name = get_saved_theme()
39
+ current_theme = THEME_CONFIGS[current_theme_name]["theme"]
40
+
41
+ class AnyCoder:
42
+ """Main AnyCoder application class"""
43
+
44
+ def __init__(self):
45
+ self.setup_cleanup()
46
+
47
+ def setup_cleanup(self):
48
+ """Setup cleanup handlers"""
49
+ cleanup_all_temp_media()
50
+ reap_old_media()
51
+
52
+ def create_advanced_ui(self):
53
+ """Create the advanced professional UI"""
54
+
55
+ with gr.Blocks(
56
+ title="AnyCoder - Professional AI Development Suite",
57
+ theme=current_theme,
58
+ css=self.get_custom_css(),
59
+ head=self.get_head_html()
60
+ ) as app:
61
+ # State management
62
+ history = gr.State([])
63
+ setting = gr.State({"system": HTML_SYSTEM_PROMPT})
64
+ current_model = gr.State(DEFAULT_MODEL)
65
+ session_state = gr.State({})
66
+
67
+ # Header
68
+ with gr.Row(elem_classes=["header-row"]):
69
+ with gr.Column(scale=3):
70
+ gr.HTML("""
71
+ <div class="app-header">
72
+ <div class="header-content">
73
+ <div class="logo-section">
74
+ <div class="logo">⚡</div>
75
+ <div class="app-title">
76
+ <h1>AnyCoder</h1>
77
+ <p>Professional AI Development Suite</p>
78
+ </div>
79
+ </div>
80
+ <div class="status-indicators">
81
+ <div class="status-item">
82
+ <span class="status-dot active"></span>
83
+ <span>AI Models Ready</span>
84
+ </div>
85
+ <div class="status-item">
86
+ <span class="status-dot active"></span>
87
+ <span>Web Search Available</span>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ """)
93
+
94
+ with gr.Column(scale=1, min_width=200):
95
+ with gr.Row():
96
+ login_button = gr.LoginButton(scale=1, size="sm")
97
+ theme_selector = gr.Dropdown(
98
+ choices=list(THEME_CONFIGS.keys()),
99
+ value=current_theme_name,
100
+ label="Theme",
101
+ scale=1,
102
+ container=False
103
+ )
104
+
105
+ # Main interface
106
+ with gr.Row():
107
+ # Left sidebar - Controls
108
+ with gr.Column(scale=1, elem_classes=["sidebar"]):
109
+ self.create_sidebar(current_model, session_state)
110
+
111
+ # Main content area
112
+ with gr.Column(scale=3, elem_classes=["main-content"]):
113
+ self.create_main_content(history, current_model)
114
+
115
+ # Connect all the event handlers
116
+ self.setup_event_handlers(app, history, setting, current_model, session_state)
117
+
118
+ return app
119
+
120
+ def create_sidebar(self, current_model, session_state):
121
+ """Create the professional sidebar"""
122
+
123
+ # Model Selection
124
+ with gr.Group(elem_classes=["control-group"]):
125
+ gr.HTML('<div class="group-title">🤖 AI Model</div>')
126
+
127
+ model_dropdown = gr.Dropdown(
128
+ choices=[f"{model['name']} ({model['category']})" for model in AVAILABLE_MODELS],
129
+ value=f"{DEFAULT_MODEL['name']} ({DEFAULT_MODEL['category']})",
130
+ label="Select Model",
131
+ info="Choose your AI model based on task requirements",
132
+ container=False
133
+ )
134
+
135
+ # Model info display
136
+ model_info = gr.HTML(self.get_model_info_html(DEFAULT_MODEL))
137
+
138
+ # Project Configuration
139
+ with gr.Group(elem_classes=["control-group"]):
140
+ gr.HTML('<div class="group-title">⚙️ Project Settings</div>')
141
+
142
+ language_dropdown = gr.Dropdown(
143
+ choices=[
144
+ ("Static HTML", "html"),
145
+ ("Streamlit App", "streamlit"),
146
+ ("Gradio App", "gradio"),
147
+ ("Transformers.js", "transformers.js"),
148
+ ("Svelte App", "svelte"),
149
+ ("Python Script", "python"),
150
+ ("JavaScript", "javascript"),
151
+ ("CSS Styles", "css"),
152
+ ("Other", "other")
153
+ ],
154
+ value="html",
155
+ label="Project Type",
156
+ container=False
157
+ )
158
+
159
+ with gr.Row():
160
+ search_toggle = gr.Checkbox(
161
+ label="Web Search",
162
+ value=False,
163
+ info="Enable real-time web search"
164
+ )
165
+ advanced_mode = gr.Checkbox(
166
+ label="Advanced Mode",
167
+ value=False,
168
+ info="Show advanced options"
169
+ )
170
+
171
+ # Input Sources
172
+ with gr.Group(elem_classes=["control-group"]):
173
+ gr.HTML('<div class="group-title">📁 Input Sources</div>')
174
+
175
+ file_input = gr.File(
176
+ label="Upload Reference File",
177
+ file_types=[".pdf", ".txt", ".md", ".csv", ".docx", ".jpg", ".jpeg", ".png"],
178
+ container=False
179
+ )
180
+
181
+ website_url_input = gr.Textbox(
182
+ label="Website URL (for redesign)",
183
+ placeholder="https://example.com",
184
+ container=False
185
+ )
186
+
187
+ image_input = gr.Image(
188
+ label="Design Reference Image",
189
+ visible=False,
190
+ container=False
191
+ )
192
+
193
+ # Media Generation Controls
194
+ with gr.Group(elem_classes=["control-group"], visible=False) as advanced_controls:
195
+ gr.HTML('<div class="group-title">🎨 Media Generation</div>')
196
+
197
+ with gr.Row():
198
+ enable_images = gr.Checkbox(label="Images", value=False, scale=1)
199
+ enable_videos = gr.Checkbox(label="Videos", value=False, scale=1)
200
+ enable_music = gr.Checkbox(label="Music", value=False, scale=1)
201
+
202
+ media_prompts = gr.Textbox(
203
+ label="Media Generation Prompts",
204
+ placeholder="Describe media to generate...",
205
+ lines=2,
206
+ visible=False,
207
+ container=False
208
+ )
209
+
210
+ # Quick Examples
211
+ with gr.Group(elem_classes=["control-group"]):
212
+ gr.HTML('<div class="group-title">🚀 Quick Start</div>')
213
+
214
+ example_gallery = gr.Gallery(
215
+ value=[(None, demo["title"]) for demo in DEMO_LIST[:6]],
216
+ label="Example Projects",
217
+ show_label=False,
218
+ elem_classes=["example-gallery"],
219
+ columns=2,
220
+ rows=3,
221
+ height="auto",
222
+ container=False
223
+ )
224
+
225
+ # Project Import
226
+ with gr.Group(elem_classes=["control-group"]):
227
+ gr.HTML('<div class="group-title">📥 Import Project</div>')
228
+
229
+ import_url = gr.Textbox(
230
+ label="GitHub/HuggingFace URL",
231
+ placeholder="https://github.com/user/repo or https://huggingface.co/spaces/user/space",
232
+ container=False
233
+ )
234
+
235
+ with gr.Row():
236
+ import_btn = gr.Button("Import", variant="secondary", scale=1)
237
+ import_status = gr.HTML("", visible=False, scale=2)
238
+
239
+ # Store sidebar components for event handling
240
+ self.sidebar_components = {
241
+ 'model_dropdown': model_dropdown,
242
+ 'model_info': model_info,
243
+ 'language_dropdown': language_dropdown,
244
+ 'search_toggle': search_toggle,
245
+ 'advanced_mode': advanced_mode,
246
+ 'file_input': file_input,
247
+ 'website_url_input': website_url_input,
248
+ 'image_input': image_input,
249
+ 'advanced_controls': advanced_controls,
250
+ 'enable_images': enable_images,
251
+ 'enable_videos': enable_videos,
252
+ 'enable_music': enable_music,
253
+ 'media_prompts': media_prompts,
254
+ 'example_gallery': example_gallery,
255
+ 'import_url': import_url,
256
+ 'import_btn': import_btn,
257
+ 'import_status': import_status
258
+ }
259
+
260
+ # Show advanced controls when enabled
261
+ advanced_mode.change(
262
+ lambda checked: gr.update(visible=checked),
263
+ inputs=[advanced_mode],
264
+ outputs=[advanced_controls]
265
+ )
266
+
267
+ # Show media prompts when any media generation is enabled
268
+ for checkbox in [enable_images, enable_videos, enable_music]:
269
+ checkbox.change(
270
+ lambda *args: gr.update(visible=any(args)),
271
+ inputs=[enable_images, enable_videos, enable_music],
272
+ outputs=[media_prompts]
273
+ )
274
+
275
+ def create_main_content(self, history, current_model):
276
+ """Create the main content area"""
277
+
278
+ # Input area
279
+ with gr.Group(elem_classes=["input-group"]):
280
+ input_textbox = gr.Textbox(
281
+ label="What would you like to build?",
282
+ placeholder="Describe your application in detail... (e.g., 'Create a modern dashboard with charts and user management')",
283
+ lines=4,
284
+ container=False,
285
+ elem_classes=["main-input"]
286
+ )
287
+
288
+ with gr.Row():
289
+ generate_btn = gr.Button(
290
+ "🚀 Generate Application",
291
+ variant="primary",
292
+ scale=3,
293
+ size="lg",
294
+ elem_classes=["generate-btn"]
295
+ )
296
+ clear_btn = gr.Button(
297
+ "🗑️ Clear",
298
+ variant="secondary",
299
+ scale=1,
300
+ size="lg"
301
+ )
302
+
303
+ # Output area with professional tabs
304
+ with gr.Tabs(elem_classes=["output-tabs"]):
305
+
306
+ # Preview Tab
307
+ with gr.Tab("🖥️ Live Preview", elem_classes=["preview-tab"]):
308
+ with gr.Group():
309
+ preview_controls = gr.HTML("""
310
+ <div class="preview-controls">
311
+ <div class="preview-info">
312
+ <span class="info-item">📱 Responsive Design</span>
313
+ <span class="info-item">⚡ Real-time Updates</span>
314
+ <span class="info-item">🔒 Sandboxed Environment</span>
315
+ </div>
316
+ </div>
317
+ """)
318
+
319
+ sandbox = gr.HTML(
320
+ label="Application Preview",
321
+ elem_classes=["preview-container"]
322
+ )
323
+
324
+ # Code Tab
325
+ with gr.Tab("💻 Source Code", elem_classes=["code-tab"]):
326
+ with gr.Row():
327
+ with gr.Column(scale=4):
328
+ code_output = gr.Code(
329
+ language="html",
330
+ lines=30,
331
+ interactive=True,
332
+ label="Generated Code",
333
+ elem_classes=["code-editor"]
334
+ )
335
+
336
+ with gr.Column(scale=1, elem_classes=["code-sidebar"]):
337
+ # Code actions
338
+ with gr.Group():
339
+ gr.HTML('<div class="group-title">🔧 Code Actions</div>')
340
+
341
+ copy_btn = gr.Button("📋 Copy Code", size="sm")
342
+ download_btn = gr.Button("💾 Download", size="sm")
343
+ format_btn = gr.Button("✨ Format", size="sm")
344
+
345
+ # Code stats
346
+ with gr.Group():
347
+ gr.HTML('<div class="group-title">📊 Code Stats</div>')
348
+ code_stats = gr.HTML(
349
+ '<div class="code-stats">Ready to generate...</div>',
350
+ elem_classes=["code-stats"]
351
+ )
352
+
353
+ # Deployment Tab
354
+ with gr.Tab("🚀 Deploy", elem_classes=["deploy-tab"]):
355
+ with gr.Row():
356
+ with gr.Column(scale=2):
357
+ with gr.Group():
358
+ gr.HTML('<div class="group-title">🌐 Deployment Options</div>')
359
+
360
+ deploy_platform = gr.Dropdown(
361
+ choices=[
362
+ ("Hugging Face Spaces", "hf_spaces"),
363
+ ("Vercel", "vercel"),
364
+ ("Netlify", "netlify"),
365
+ ("GitHub Pages", "github_pages")
366
+ ],
367
+ value="hf_spaces",
368
+ label="Platform",
369
+ container=False
370
+ )
371
+
372
+ app_name = gr.Textbox(
373
+ label="Application Name",
374
+ placeholder="my-awesome-app",
375
+ container=False
376
+ )
377
+
378
+ deploy_btn = gr.Button(
379
+ "🚀 Deploy Now",
380
+ variant="primary",
381
+ size="lg"
382
+ )
383
+
384
+ with gr.Column(scale=1):
385
+ deployment_status = gr.HTML(
386
+ '<div class="deployment-status">Ready to deploy</div>',
387
+ elem_classes=["deployment-status"]
388
+ )
389
+
390
+ # Generation status
391
+ generation_status = gr.HTML(
392
+ visible=False,
393
+ elem_classes=["generation-status"]
394
+ )
395
+
396
+ # Store main content components
397
+ self.main_components = {
398
+ 'input_textbox': input_textbox,
399
+ 'generate_btn': generate_btn,
400
+ 'clear_btn': clear_btn,
401
+ 'sandbox': sandbox,
402
+ 'code_output': code_output,
403
+ 'code_stats': code_stats,
404
+ 'copy_btn': copy_btn,
405
+ 'download_btn': download_btn,
406
+ 'format_btn': format_btn,
407
+ 'deploy_platform': deploy_platform,
408
+ 'app_name': app_name,
409
+ 'deploy_btn': deploy_btn,
410
+ 'deployment_status': deployment_status,
411
+ 'generation_status': generation_status
412
+ }
413
+
414
+ def setup_event_handlers(self, app, history, setting, current_model, session_state):
415
+ """Setup all event handlers for the application"""
416
+
417
+ # Generation handler
418
+ self.main_components['generate_btn'].click(
419
+ self.handle_generation,
420
+ inputs=[
421
+ self.main_components['input_textbox'],
422
+ self.sidebar_components['file_input'],
423
+ self.sidebar_components['website_url_input'],
424
+ self.sidebar_components['image_input'],
425
+ self.sidebar_components['language_dropdown'],
426
+ self.sidebar_components['search_toggle'],
427
+ current_model,
428
+ history,
429
+ session_state
430
+ ],
431
+ outputs=[
432
+ self.main_components['code_output'],
433
+ self.main_components['sandbox'],
434
+ self.main_components['code_stats'],
435
+ history
436
+ ]
437
+ )
438
+
439
+ # Model selection handler
440
+ self.sidebar_components['model_dropdown'].change(
441
+ self.handle_model_change,
442
+ inputs=[self.sidebar_components['model_dropdown']],
443
+ outputs=[current_model, self.sidebar_components['model_info']]
444
+ )
445
+
446
+ # Clear handler
447
+ self.main_components['clear_btn'].click(
448
+ self.handle_clear,
449
+ outputs=[
450
+ self.main_components['input_textbox'],
451
+ self.main_components['code_output'],
452
+ self.main_components['sandbox'],
453
+ self.main_components['code_stats'],
454
+ history
455
+ ]
456
+ )
457
+
458
+ # Example selection handler
459
+ self.sidebar_components['example_gallery'].select(
460
+ self.handle_example_select,
461
+ inputs=[self.sidebar_components['example_gallery']],
462
+ outputs=[self.main_components['input_textbox']]
463
+ )
464
+
465
+ def handle_generation(self, prompt, file, website_url, image, language,
466
+ enable_search, current_model_state, history_state, session_state):
467
+ """Handle code generation with advanced features"""
468
+
469
+ if not prompt.strip():
470
+ return (
471
+ gr.update(),
472
+ "<div class='error-message'>Please enter a description of what you'd like to build.</div>",
473
+ "<div class='code-stats error'>No input provided</div>",
474
+ history_state
475
+ )
476
+
477
+ try:
478
+ # Setup session
479
+ session_id = session_state.get('session_id', str(uuid.uuid4()))
480
+ session_state['session_id'] = session_id
481
+
482
+ # Enhance prompt with file content
483
+ enhanced_prompt = prompt
484
+ if file:
485
+ file_content = extract_text_from_file(file.name)
486
+ if file_content:
487
+ enhanced_prompt = f"{prompt}\n\n[Reference file content]\n{file_content[:5000]}"
488
+
489
+ # Enhance with website content
490
+ if website_url and website_url.strip():
491
+ website_content = extract_website_content(website_url.strip())
492
+ if website_content and not website_content.startswith("Error"):
493
+ enhanced_prompt = f"{enhanced_prompt}\n\n[Website content to redesign]\n{website_content[:8000]}"
494
+
495
+ # Enhance with web search if enabled
496
+ if enable_search:
497
+ enhanced_prompt = enhance_query_with_search(enhanced_prompt, True)
498
+
499
+ # Generate code using selected model
500
+ generated_code = self.generate_code_with_model(
501
+ enhanced_prompt, current_model_state, language, image
502
+ )
503
+
504
+ # Process the generated code
505
+ processed_code = remove_code_block(generated_code)
506
+
507
+ # Apply media generation if enabled
508
+ if any([
509
+ session_state.get('enable_images', False),
510
+ session_state.get('enable_videos', False),
511
+ session_state.get('enable_music', False)
512
+ ]):
513
+ processed_code = apply_generated_media_to_html(
514
+ processed_code,
515
+ prompt,
516
+ enable_text_to_image=session_state.get('enable_images', False),
517
+ enable_text_to_video=session_state.get('enable_videos', False),
518
+ enable_text_to_music=session_state.get('enable_music', False),
519
+ session_id=session_id
520
+ )
521
+
522
+ # Generate preview
523
+ preview_html = self.generate_preview(processed_code, language)
524
+
525
+ # Update code stats
526
+ stats_html = self.generate_code_stats(processed_code, language)
527
+
528
+ # Update history
529
+ history_state.append([prompt, processed_code])
530
+
531
+ return (
532
+ gr.update(value=processed_code, language=get_gradio_language(language)),
533
+ preview_html,
534
+ stats_html,
535
+ history_state
536
+ )
537
+
538
+ except Exception as e:
539
+ error_html = f"<div class='error-message'>Generation Error: {str(e)}</div>"
540
+ return (
541
+ gr.update(value=f"// Error: {str(e)}"),
542
+ error_html,
543
+ "<div class='code-stats error'>Generation failed</div>",
544
+ history_state
545
+ )
546
+
547
+ def generate_code_with_model(self, prompt, model_state, language, image):
548
+ """Generate code using the selected model"""
549
+
550
+ try:
551
+ client = get_inference_client(model_state['id'], "auto")
552
+
553
+ # Select appropriate system prompt based on language
554
+ system_prompts = {
555
+ 'html': HTML_SYSTEM_PROMPT,
556
+ 'streamlit': "You are an expert Streamlit developer. Create modern, interactive Streamlit applications with clean code and professional UI.",
557
+ 'gradio': "You are an expert Gradio developer. Create modern, interactive Gradio applications with clean interfaces and robust functionality.",
558
+ 'transformers.js': "You are an expert in Transformers.js. Create modern web applications using Transformers.js for AI/ML functionality.",
559
+ 'svelte': "You are an expert Svelte developer. Create modern, reactive Svelte applications with TypeScript and clean architecture."
560
+ }
561
+
562
+ system_prompt = system_prompts.get(language, HTML_SYSTEM_PROMPT)
563
+
564
+ # Prepare messages
565
+ messages = [
566
+ {"role": "system", "content": system_prompt}
567
+ ]
568
+
569
+ if image:
570
+ messages.append(create_multimodal_message(prompt, image))
571
+ else:
572
+ messages.append({"role": "user", "content": prompt})
573
+
574
+ # Generate with streaming for better UX
575
+ if hasattr(client, 'chat') and hasattr(client.chat, 'completions'):
576
+ completion = client.chat.completions.create(
577
+ model=model_state['id'],
578
+ messages=messages,
579
+ max_tokens=16384,
580
+ temperature=0.7,
581
+ stream=False # For simplicity in this demo
582
+ )
583
+
584
+ return completion.choices[0].message.content
585
+ else:
586
+ # Fallback for different client types
587
+ return "Generated code would appear here..."
588
+
589
+ except Exception as e:
590
+ raise Exception(f"Model generation failed: {str(e)}")
591
+
592
+ def generate_preview(self, code, language):
593
+ """Generate HTML preview for the code"""
594
+
595
+ try:
596
+ if language == "html":
597
+ # Handle multi-page HTML
598
+ files = parse_multipage_html_output(code)
599
+ if files and files.get('index.html'):
600
+ files = validate_and_autofix_files(files)
601
+ preview_code = inline_multipage_into_single_preview(files)
602
+ else:
603
+ preview_code = extract_html_document(code)
604
+
605
+ return self.send_to_sandbox(preview_code)
606
+
607
+ elif language == "transformers.js":
608
+ files = parse_transformers_js_output(code)
609
+ if files['index.html'] and files['index.js'] and files['style.css']:
610
+ merged_html = build_transformers_inline_html(files)
611
+ return self.send_to_sandbox(merged_html)
612
+ else:
613
+ return "<div class='preview-message'>⏳ Generating Transformers.js application...</div>"
614
+
615
+ elif language == "streamlit":
616
+ if is_streamlit_code(code):
617
+ return self.send_streamlit_to_stlite(code)
618
+ else:
619
+ return "<div class='preview-message'>Add <code>import streamlit as st</code> to enable preview</div>"
620
+
621
+ elif language == "gradio":
622
+ if is_gradio_code(code):
623
+ return self.send_gradio_to_lite(code)
624
+ else:
625
+ return "<div class='preview-message'>Add <code>import gradio as gr</code> to enable preview</div>"
626
+
627
+ else:
628
+ return f"<div class='preview-message'>💻 {language.upper()} code generated successfully. Preview not available for this language.</div>"
629
+
630
+ except Exception as e:
631
+ return f"<div class='error-message'>Preview Error: {str(e)}</div>"
632
+
633
+ def send_to_sandbox(self, html_code):
634
+ """Send HTML to sandboxed iframe"""
635
+ if not html_code.strip():
636
+ return "<div class='preview-message'>No content to preview</div>"
637
+
638
+ try:
639
+ encoded_html = base64.b64encode(html_code.encode('utf-8')).decode('utf-8')
640
+ data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
641
+ iframe = f'''
642
+ <iframe
643
+ src="{data_uri}"
644
+ width="100%"
645
+ height="800px"
646
+ sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals"
647
+ style="border: 1px solid #e5e7eb; border-radius: 8px; background: white;"
648
+ allow="display-capture">
649
+ </iframe>
650
+ '''
651
+ return iframe
652
+ except Exception as e:
653
+ return f"<div class='error-message'>Sandbox Error: {str(e)}</div>"
654
+
655
+ def send_streamlit_to_stlite(self, code):
656
+ """Send Streamlit code to stlite preview"""
657
+ html_doc = f"""
658
+ <!doctype html>
659
+ <html>
660
+ <head>
661
+ <meta charset="UTF-8" />
662
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
663
+ <title>Streamlit Preview</title>
664
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@stlite/[email protected]/build/stlite.css" />
665
+ <script type="module" src="https://cdn.jsdelivr.net/npm/@stlite/[email protected]/build/stlite.js"></script>
666
+ </head>
667
+ <body>
668
+ <streamlit-app>{code}</streamlit-app>
669
+ </body>
670
+ </html>
671
+ """
672
+ return self.send_to_sandbox(html_doc)
673
+
674
+ def send_gradio_to_lite(self, code):
675
+ """Send Gradio code to gradio-lite preview"""
676
+ html_doc = f"""
677
+ <!doctype html>
678
+ <html>
679
+ <head>
680
+ <meta charset="UTF-8" />
681
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
682
+ <title>Gradio Preview</title>
683
+ <script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.js"></script>
684
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@gradio/lite/dist/lite.css" />
685
+ </head>
686
+ <body>
687
+ <gradio-lite>{code}</gradio-lite>
688
+ </body>
689
+ </html>
690
+ """
691
+ return self.send_to_sandbox(html_doc)
692
+
693
+ def generate_code_stats(self, code, language):
694
+ """Generate code statistics"""
695
+ if not code:
696
+ return "<div class='code-stats'>No code generated</div>"
697
+
698
+ try:
699
+ lines = len(code.split('\n'))
700
+ chars = len(code)
701
+ words = len(code.split())
702
+
703
+ # Language-specific analysis
704
+ if language == "html":
705
+ tags = len([m for m in code.split('<') if m.strip()])
706
+ stats_content = f"""
707
+ <div class='stats-grid'>
708
+ <div class='stat-item'>
709
+ <span class='stat-number'>{lines}</span>
710
+ <span class='stat-label'>Lines</span>
711
+ </div>
712
+ <div class='stat-item'>
713
+ <span class='stat-number'>{tags}</span>
714
+ <span class='stat-label'>HTML Tags</span>
715
+ </div>
716
+ <div class='stat-item'>
717
+ <span class='stat-number'>{chars}</span>
718
+ <span class='stat-label'>Characters</span>
719
+ </div>
720
+ <div class='stat-item'>
721
+ <span class='stat-number'>{round(chars/1024, 1)}KB</span>
722
+ <span class='stat-label'>Size</span>
723
+ </div>
724
+ </div>
725
+ """
726
+ else:
727
+ stats_content = f"""
728
+ <div class='stats-grid'>
729
+ <div class='stat-item'>
730
+ <span class='stat-number'>{lines}</span>
731
+ <span class='stat-label'>Lines</span>
732
+ </div>
733
+ <div class='stat-item'>
734
+ <span class='stat-number'>{words}</span>
735
+ <span class='stat-label'>Words</span>
736
+ </div>
737
+ <div class='stat-item'>
738
+ <span class='stat-number'>{chars}</span>
739
+ <span class='stat-label'>Characters</span>
740
+ </div>
741
+ <div class='stat-item'>
742
+ <span class='stat-number'>{language.upper()}</span>
743
+ <span class='stat-label'>Language</span>
744
+ </div>
745
+ </div>
746
+ """
747
+
748
+ return f"<div class='code-stats'>{stats_content}</div>"
749
+
750
+ except Exception:
751
+ return "<div class='code-stats'>Unable to analyze code</div>"
752
+
753
+ def handle_model_change(self, model_selection):
754
+ """Handle model selection change"""
755
+ try:
756
+ # Extract model name from selection
757
+ model_name = model_selection.split(" (")[0]
758
+
759
+ # Find the model
760
+ selected_model = None
761
+ for model in AVAILABLE_MODELS:
762
+ if model['name'] == model_name:
763
+ selected_model = model
764
+ break
765
+
766
+ if selected_model:
767
+ model_info_html = self.get_model_info_html(selected_model)
768
+ return selected_model, model_info_html
769
+
770
+ return DEFAULT_MODEL, self.get_model_info_html(DEFAULT_MODEL)
771
+
772
+ except Exception:
773
+ return DEFAULT_MODEL, self.get_model_info_html(DEFAULT_MODEL)
774
+
775
+ def handle_clear(self):
776
+ """Handle clear button"""
777
+ return (
778
+ gr.update(value=""), # input_textbox
779
+ gr.update(value="", language="html"), # code_output
780
+ "<div class='preview-message'>Ready to generate your next application</div>", # sandbox
781
+ "<div class='code-stats'>Ready to generate...</div>", # code_stats
782
+ [] # history
783
+ )
784
+
785
+ def handle_example_select(self, evt: gr.SelectData):
786
+ """Handle example selection from gallery"""
787
+ try:
788
+ if evt.index is not None and evt.index < len(DEMO_LIST):
789
+ return DEMO_LIST[evt.index]['description']
790
+ return ""
791
+ except Exception:
792
+ return ""
793
+
794
+ def get_model_info_html(self, model):
795
+ """Generate HTML for model information"""
796
+ vision_badge = '<span class="feature-badge vision">👁️ Vision</span>' if model.get('supports_vision') else ''
797
+ category_color = {
798
+ 'General': '#3b82f6',
799
+ 'Code Specialist': '#10b981',
800
+ 'Vision-Language': '#f59e0b',
801
+ 'Premium': '#8b5cf6'
802
+ }.get(model.get('category', 'General'), '#6b7280')
803
+
804
+ return f"""
805
+ <div class="model-info">
806
+ <div class="model-header">
807
+ <div class="model-name">{model['name']}</div>
808
+ <span class="category-badge" style="background-color: {category_color}">
809
+ {model.get('category', 'General')}
810
+ </span>
811
+ </div>
812
+ <div class="model-description">{model.get('description', '')}</div>
813
+ <div class="model-features">
814
+ {vision_badge}
815
+ <span class="feature-badge">🚀 Latest</span>
816
+ </div>
817
+ </div>
818
+ """
819
+
820
+ def get_custom_css(self):
821
+ """Get custom CSS for the application"""
822
+ return """
823
+ /* Modern Professional Styling */
824
+ .gradio-container {
825
+ max-width: none !important;
826
+ padding: 0 !important;
827
+ }
828
+
829
+ .app-header {
830
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
831
+ color: white;
832
+ padding: 20px;
833
+ border-radius: 0 0 16px 16px;
834
+ margin-bottom: 20px;
835
+ }
836
+
837
+ .header-content {
838
+ display: flex;
839
+ justify-content: space-between;
840
+ align-items: center;
841
+ max-width: 1400px;
842
+ margin: 0 auto;
843
+ }
844
+
845
+ .logo-section {
846
+ display: flex;
847
+ align-items: center;
848
+ gap: 15px;
849
+ }
850
+
851
+ .logo {
852
+ font-size: 2.5rem;
853
+ font-weight: bold;
854
+ }
855
+
856
+ .app-title h1 {
857
+ font-size: 2rem;
858
+ margin: 0;
859
+ font-weight: 700;
860
+ }
861
+
862
+ .app-title p {
863
+ margin: 5px 0 0 0;
864
+ opacity: 0.9;
865
+ font-size: 1rem;
866
+ }
867
+
868
+ .status-indicators {
869
+ display: flex;
870
+ flex-direction: column;
871
+ gap: 8px;
872
+ }
873
+
874
+ .status-item {
875
+ display: flex;
876
+ align-items: center;
877
+ gap: 8px;
878
+ font-size: 0.9rem;
879
+ }
880
+
881
+ .status-dot {
882
+ width: 8px;
883
+ height: 8px;
884
+ border-radius: 50%;
885
+ background: #10b981;
886
+ }
887
+
888
+ .status-dot.active {
889
+ animation: pulse 2s infinite;
890
+ }
891
+
892
+ @keyframes pulse {
893
+ 0%, 100% { opacity: 1; }
894
+ 50% { opacity: 0.5; }
895
+ }
896
+
897
+ .sidebar {
898
+ background: #f8fafc;
899
+ padding: 20px;
900
+ border-radius: 12px;
901
+ border: 1px solid #e2e8f0;
902
+ height: fit-content;
903
+ }
904
+
905
+ .main-content {
906
+ padding-left: 20px;
907
+ }
908
+
909
+ .control-group {
910
+ margin-bottom: 24px;
911
+ background: white;
912
+ padding: 16px;
913
+ border-radius: 8px;
914
+ border: 1px solid #e5e7eb;
915
+ }
916
+
917
+ .group-title {
918
+ font-weight: 600;
919
+ font-size: 0.95rem;
920
+ color: #374151;
921
+ margin-bottom: 12px;
922
+ display: flex;
923
+ align-items: center;
924
+ gap: 8px;
925
+ }
926
+
927
+ .input-group {
928
+ background: white;
929
+ padding: 24px;
930
+ border-radius: 12px;
931
+ border: 1px solid #e2e8f0;
932
+ margin-bottom: 20px;
933
+ box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
934
+ }
935
+
936
+ .main-input textarea {
937
+ font-size: 16px !important;
938
+ line-height: 1.5 !important;
939
+ }
940
+
941
+ .generate-btn {
942
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
943
+ border: none !important;
944
+ font-weight: 600 !important;
945
+ font-size: 1.1rem !important;
946
+ padding: 16px 32px !important;
947
+ }
948
+
949
+ .generate-btn:hover {
950
+ transform: translateY(-1px);
951
+ box-shadow: 0 10px 25px rgba(16, 185, 129, 0.3) !important;
952
+ }
953
+
954
+ .output-tabs .tab-nav {
955
+ background: #f8fafc;
956
+ border-radius: 8px 8px 0 0;
957
+ border-bottom: 1px solid #e2e8f0;
958
+ }
959
+
960
+ .preview-container iframe {
961
+ border-radius: 8px;
962
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
963
+ }
964
+
965
+ .code-editor {
966
+ border-radius: 8px;
967
+ border: 1px solid #e2e8f0;
968
+ }
969
+
970
+ .code-sidebar {
971
+ padding-left: 16px;
972
+ }
973
+
974
+ .code-sidebar .control-group {
975
+ margin-bottom: 16px;
976
+ padding: 12px;
977
+ }
978
+
979
+ .code-stats {
980
+ background: white;
981
+ padding: 16px;
982
+ border-radius: 8px;
983
+ border: 1px solid #e5e7eb;
984
+ }
985
+
986
+ .stats-grid {
987
+ display: grid;
988
+ grid-template-columns: 1fr 1fr;
989
+ gap: 12px;
990
+ }
991
+
992
+ .stat-item {
993
+ text-align: center;
994
+ padding: 8px;
995
+ background: #f8fafc;
996
+ border-radius: 6px;
997
+ }
998
+
999
+ .stat-number {
1000
+ display: block;
1001
+ font-size: 1.25rem;
1002
+ font-weight: 700;
1003
+ color: #1f2937;
1004
+ }
1005
+
1006
+ .stat-label {
1007
+ font-size: 0.75rem;
1008
+ color: #6b7280;
1009
+ text-transform: uppercase;
1010
+ letter-spacing: 0.05em;
1011
+ }
1012
+
1013
+ .model-info {
1014
+ background: white;
1015
+ padding: 12px;
1016
+ border-radius: 6px;
1017
+ border: 1px solid #e5e7eb;
1018
+ margin-top: 8px;
1019
+ }
1020
+
1021
+ .model-header {
1022
+ display: flex;
1023
+ justify-content: space-between;
1024
+ align-items: center;
1025
+ margin-bottom: 8px;
1026
+ }
1027
+
1028
+ .model-name {
1029
+ font-weight: 600;
1030
+ color: #1f2937;
1031
+ }
1032
+
1033
+ .category-badge {
1034
+ padding: 2px 8px;
1035
+ border-radius: 12px;
1036
+ font-size: 0.75rem;
1037
+ font-weight: 500;
1038
+ color: white;
1039
+ }
1040
+
1041
+ .model-description {
1042
+ font-size: 0.85rem;
1043
+ color: #6b7280;
1044
+ margin-bottom: 8px;
1045
+ }
1046
+
1047
+ .model-features {
1048
+ display: flex;
1049
+ gap: 4px;
1050
+ }
1051
+
1052
+ .feature-badge {
1053
+ padding: 2px 6px;
1054
+ border-radius: 8px;
1055
+ font-size: 0.7rem;
1056
+ font-weight: 500;
1057
+ background: #f3f4f6;
1058
+ color: #374151;
1059
+ }
1060
+
1061
+ .feature-badge.vision {
1062
+ background: #fef3c7;
1063
+ color: #92400e;
1064
+ }
1065
+
1066
+ .example-gallery {
1067
+ border-radius: 8px;
1068
+ border: 1px solid #e5e7eb;
1069
+ }
1070
+
1071
+ .preview-message {
1072
+ text-align: center;
1073
+ padding: 40px 20px;
1074
+ color: #6b7280;
1075
+ background: #f9fafb;
1076
+ border-radius: 8px;
1077
+ border: 2px dashed #d1d5db;
1078
+ }
1079
+
1080
+ .error-message {
1081
+ text-align: center;
1082
+ padding: 20px;
1083
+ color: #dc2626;
1084
+ background: #fef2f2;
1085
+ border: 1px solid #fecaca;
1086
+ border-radius: 8px;
1087
+ }
1088
+
1089
+ .deployment-status {
1090
+ background: white;
1091
+ padding: 16px;
1092
+ border-radius: 8px;
1093
+ border: 1px solid #e5e7eb;
1094
+ text-align: center;
1095
+ color: #6b7280;
1096
+ }
1097
+
1098
+ /* Dark mode adjustments */
1099
+ .dark .sidebar {
1100
+ background: #1f2937;
1101
+ border-color: #374151;
1102
+ }
1103
+
1104
+ .dark .control-group {
1105
+ background: #111827;
1106
+ border-color: #374151;
1107
+ }
1108
+
1109
+ .dark .input-group {
1110
+ background: #111827;
1111
+ border-color: #374151;
1112
+ }
1113
+
1114
+ /* Responsive design */
1115
+ @media (max-width: 768px) {
1116
+ .header-content {
1117
+ flex-direction: column;
1118
+ gap: 20px;
1119
+ text-align: center;
1120
+ }
1121
+
1122
+ .stats-grid {
1123
+ grid-template-columns: 1fr;
1124
+ }
1125
+
1126
+ .main-content {
1127
+ padding-left: 0;
1128
+ margin-top: 20px;
1129
+ }
1130
+ }
1131
+ """
1132
+
1133
+ def get_head_html(self):
1134
+ """Get additional head HTML"""
1135
+ return """
1136
+ <meta name="description" content="AnyCoder - Professional AI Development Suite for creating modern applications">
1137
+ <meta name="keywords" content="AI, code generation, web development, automation">
1138
+ <meta name="author" content="AnyCoder">
1139
+ <link rel="preconnect" href="https://fonts.googleapis.com">
1140
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
1141
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
1142
+ <style>
1143
+ body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; }
1144
+ </style>
1145
+ """
1146
+
1147
+ def main():
1148
+ """Main application entry point"""
1149
+ print("🚀 Starting AnyCoder Professional AI Development Suite...")
1150
+
1151
+ # Initialize the application
1152
+ app_instance = AnyCoder()
1153
+ demo = app_instance.create_advanced_ui()
1154
+
1155
+ # Launch with optimal settings
1156
+ demo.queue(api_open=False, default_concurrency_limit=20).launch(
1157
+ show_api=False,
1158
+ share=False,
1159
+ server_name="0.0.0.0",
1160
+ server_port=7860,
1161
+ show_error=True,
1162
+ quiet=False
1163
+ )
1164
+
1165
+ if __name__ == "__main__":
1166
+ main()
app.py DELETED
@@ -1,848 +0,0 @@
1
- """
2
- Main AnyCoder application with advanced professional UI.
3
- """
4
-
5
- import os
6
- import uuid
7
- import time
8
- from typing import Dict, List, Optional, Tuple, Any
9
- import gradio as gr
10
-
11
- # Import all modules
12
- from config import (
13
- AVAILABLE_MODELS, DEFAULT_MODEL, THEME_CONFIGS, DEMO_LIST,
14
- get_gradio_language, get_saved_theme, save_theme_preference
15
- )
16
- from utils import (
17
- get_inference_client, remove_code_block, extract_text_from_file,
18
- create_multimodal_message, apply_search_replace_changes,
19
- cleanup_all_temp_media, cleanup_session_media, reap_old_media
20
- )
21
- from media_generation import (
22
- generate_image_with_qwen, generate_image_to_image, generate_video_from_image,
23
- generate_video_from_text, generate_music_from_text
24
- )
25
- from web_utils import extract_website_content, enhance_query_with_search, tavily_client
26
- from code_processing import (
27
- is_streamlit_code, is_gradio_code, parse_transformers_js_output,
28
- format_transformers_js_output, parse_svelte_output, format_svelte_output,
29
- parse_multipage_html_output, format_multipage_output, validate_and_autofix_files,
30
- inline_multipage_into_single_preview, apply_generated_media_to_html,
31
- extract_html_document, apply_search_replace_changes as apply_transformers_js_search_replace_changes
32
- )
33
- from sandbox import (
34
- send_to_sandbox, send_to_sandbox_with_refresh, send_streamlit_to_stlite,
35
- send_gradio_to_lite, send_transformers_to_sandbox, generate_preview
36
- )
37
- from deployment import (
38
- deploy_to_user_space, deploy_to_spaces, deploy_to_spaces_static,
39
- load_project_from_url, extract_import_statements
40
- )
41
-
42
- # Global state
43
- History = List[Tuple[str, str]]
44
- Messages = List[Dict[str, str]]
45
-
46
- def history_to_messages(history: History, system: str) -> Messages:
47
- """Convert history to messages format"""
48
- messages = [{'role': 'system', 'content': system}]
49
- for h in history:
50
- user_content = h[0]
51
- if isinstance(user_content, list):
52
- text_content = ""
53
- for item in user_content:
54
- if isinstance(item, dict) and item.get("type") == "text":
55
- text_content += item.get("text", "")
56
- user_content = text_content if text_content else str(user_content)
57
-
58
- messages.append({'role': 'user', 'content': user_content})
59
- messages.append({'role': 'assistant', 'content': h[1]})
60
- return messages
61
-
62
- def history_to_chatbot_messages(history: History) -> List[Dict[str, str]]:
63
- """Convert history tuples to chatbot message format"""
64
- messages = []
65
- for user_msg, assistant_msg in history:
66
- if isinstance(user_msg, list):
67
- text_content = ""
68
- for item in user_msg:
69
- if isinstance(item, dict) and item.get("type") == "text":
70
- text_content += item.get("text", "")
71
- user_msg = text_content if text_content else str(user_msg)
72
-
73
- messages.append({"role": "user", "content": user_msg})
74
- messages.append({"role": "assistant", "content": assistant_msg})
75
- return messages
76
-
77
- def clear_history():
78
- """Clear all history and reset UI"""
79
- return [], [], None, ""
80
-
81
- def update_image_input_visibility(model):
82
- """Update image input visibility based on selected model"""
83
- is_vision_model = model.get("supports_vision", False)
84
- return gr.update(visible=is_vision_model)
85
-
86
- def generation_code(query: Optional[str], vlm_image: Optional[gr.Image], gen_image: Optional[gr.Image],
87
- file: Optional[str], website_url: Optional[str], _setting: Dict[str, str],
88
- _history: Optional[History], _current_model: Dict, enable_search: bool = False,
89
- language: str = "html", provider: str = "auto", enable_image_generation: bool = False,
90
- enable_image_to_image: bool = False, image_to_image_prompt: Optional[str] = None,
91
- text_to_image_prompt: Optional[str] = None, enable_image_to_video: bool = False,
92
- image_to_video_prompt: Optional[str] = None, enable_text_to_video: bool = False,
93
- text_to_video_prompt: Optional[str] = None, enable_text_to_music: bool = False,
94
- text_to_music_prompt: Optional[str] = None):
95
- """Main code generation function"""
96
-
97
- if query is None:
98
- query = ''
99
- if _history is None:
100
- _history = []
101
-
102
- # Ensure proper history format
103
- if not isinstance(_history, list):
104
- _history = []
105
- _history = [h for h in _history if isinstance(h, list) and len(h) == 2]
106
-
107
- # Create/lookup session ID for temp file tracking
108
- if _setting is not None and isinstance(_setting, dict):
109
- session_id = _setting.get("__session_id__")
110
- if not session_id:
111
- session_id = str(uuid.uuid4())
112
- _setting["__session_id__"] = session_id
113
- else:
114
- session_id = str(uuid.uuid4())
115
-
116
- # Cleanup old files
117
- try:
118
- cleanup_session_media(session_id)
119
- reap_old_media()
120
- except Exception:
121
- pass
122
-
123
- # Check for existing content (modification request)
124
- has_existing_content = False
125
- last_assistant_msg = ""
126
- if _history and len(_history[-1]) > 1:
127
- last_assistant_msg = _history[-1][1]
128
- if any(indicator in last_assistant_msg for indicator in [
129
- '<!DOCTYPE html>', '<html', 'import gradio', 'import streamlit',
130
- 'def ', '=== index.html ===', '=== index.js ===', '=== style.css ==='
131
- ]):
132
- has_existing_content = True
133
-
134
- # Handle modification requests with search/replace
135
- if has_existing_content and query.strip():
136
- try:
137
- client = get_inference_client(_current_model['id'], provider)
138
-
139
- system_prompt = f"""You are a code editor assistant. Generate EXACT search/replace blocks using these markers:
140
- {from config import SEARCH_START, DIVIDER, REPLACE_END}
141
-
142
- CRITICAL REQUIREMENTS:
143
- 1. Use EXACTLY these markers: {SEARCH_START}, {DIVIDER}, {REPLACE_END}
144
- 2. The SEARCH block must match existing code EXACTLY (whitespace, indentation, line breaks)
145
- 3. Generate multiple blocks if needed for different changes
146
- 4. Include enough context to make search blocks unique
147
- 5. Do NOT include explanations outside the blocks"""
148
-
149
- user_prompt = f"""Existing code:
150
- {last_assistant_msg}
151
-
152
- Modification instructions:
153
- {query}
154
-
155
- Generate the exact search/replace blocks needed."""
156
-
157
- messages = [
158
- {"role": "system", "content": system_prompt},
159
- {"role": "user", "content": user_prompt}
160
- ]
161
-
162
- # Generate search/replace instructions
163
- if hasattr(client, 'chat'):
164
- if hasattr(client.chat, 'completions'):
165
- response = client.chat.completions.create(
166
- model=_current_model['id'],
167
- messages=messages,
168
- max_tokens=4000,
169
- temperature=0.1
170
- )
171
- changes_text = response.choices[0].message.content
172
- else:
173
- response = client.chat.complete(
174
- model=_current_model['id'],
175
- messages=messages,
176
- max_tokens=4000,
177
- temperature=0.1
178
- )
179
- changes_text = response.choices[0].message.content
180
- else:
181
- completion = client.chat.completions.create(
182
- model=_current_model['id'],
183
- messages=messages,
184
- max_tokens=4000,
185
- temperature=0.1
186
- )
187
- changes_text = completion.choices[0].message.content
188
-
189
- # Apply changes
190
- if language == "transformers.js" and ('=== index.html ===' in last_assistant_msg):
191
- modified_content = apply_transformers_js_search_replace_changes(last_assistant_msg, changes_text)
192
- else:
193
- modified_content = apply_search_replace_changes(last_assistant_msg, changes_text)
194
-
195
- # If changes were applied, return modified content
196
- if modified_content != last_assistant_msg:
197
- _history.append([query, modified_content])
198
-
199
- # Generate preview
200
- preview_val = generate_preview(modified_content, language)
201
-
202
- yield {
203
- code_output: modified_content,
204
- history: _history,
205
- sandbox: preview_val,
206
- history_output: history_to_chatbot_messages(_history),
207
- }
208
- return
209
-
210
- except Exception as e:
211
- print(f"Search/replace failed, falling back to normal generation: {e}")
212
-
213
- # Choose appropriate system prompt
214
- from config import HTML_SYSTEM_PROMPT, TRANSFORMERS_JS_SYSTEM_PROMPT, SVELTE_SYSTEM_PROMPT, GENERIC_SYSTEM_PROMPT
215
-
216
- if language == "html":
217
- system_prompt = HTML_SYSTEM_PROMPT
218
- elif language == "transformers.js":
219
- system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT
220
- elif language == "svelte":
221
- system_prompt = SVELTE_SYSTEM_PROMPT
222
- else:
223
- system_prompt = GENERIC_SYSTEM_PROMPT.format(language=language)
224
-
225
- messages = history_to_messages(_history, system_prompt)
226
-
227
- # Process file input
228
- file_text = ""
229
- if file:
230
- file_text = extract_text_from_file(file)
231
- if file_text:
232
- file_text = file_text[:5000]
233
- query = f"{query}\n\n[Reference file content]\n{file_text}"
234
-
235
- # Process website URL
236
- if website_url and website_url.strip():
237
- website_text = extract_website_content(website_url.strip())
238
- if website_text and not website_text.startswith("Error"):
239
- website_text = website_text[:8000]
240
- query = f"{query}\n\n[Website content to redesign]\n{website_text}"
241
-
242
- # Enhance with web search if enabled
243
- enhanced_query = enhance_query_with_search(query, enable_search)
244
-
245
- # Add message
246
- if vlm_image is not None:
247
- messages.append(create_multimodal_message(enhanced_query, vlm_image))
248
- else:
249
- messages.append({'role': 'user', 'content': enhanced_query})
250
-
251
- # Generate code using the appropriate client
252
- try:
253
- client = get_inference_client(_current_model["id"], provider)
254
-
255
- # Stream generation
256
- if hasattr(client, 'chat') and hasattr(client.chat, 'completions'):
257
- completion = client.chat.completions.create(
258
- model=_current_model["id"],
259
- messages=messages,
260
- stream=True,
261
- max_tokens=16384
262
- )
263
- else:
264
- # Handle other client types
265
- completion = client.chat.completions.create(
266
- model=_current_model["id"],
267
- messages=messages,
268
- stream=True,
269
- max_tokens=16384
270
- )
271
-
272
- content = ""
273
- for chunk in completion:
274
- chunk_content = None
275
- if hasattr(chunk, "choices") and chunk.choices:
276
- if hasattr(chunk.choices[0], "delta") and hasattr(chunk.choices[0].delta, "content"):
277
- chunk_content = chunk.choices[0].delta.content
278
-
279
- if chunk_content:
280
- content += chunk_content
281
-
282
- # Generate live preview
283
- clean_code = remove_code_block(content)
284
- preview_val = generate_preview(clean_code, language)
285
-
286
- yield {
287
- code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
288
- history_output: history_to_chatbot_messages(_history),
289
- sandbox: preview_val,
290
- }
291
-
292
- # Final processing
293
- final_content = remove_code_block(content)
294
-
295
- # Apply media generation
296
- final_content = apply_generated_media_to_html(
297
- final_content,
298
- query,
299
- enable_text_to_image=enable_image_generation,
300
- enable_image_to_image=enable_image_to_image,
301
- input_image_data=gen_image,
302
- image_to_image_prompt=image_to_image_prompt,
303
- text_to_image_prompt=text_to_image_prompt,
304
- enable_image_to_video=enable_image_to_video,
305
- image_to_video_prompt=image_to_video_prompt,
306
- session_id=session_id,
307
- enable_text_to_video=enable_text_to_video,
308
- text_to_video_prompt=text_to_video_prompt,
309
- enable_text_to_music=enable_text_to_music,
310
- text_to_music_prompt=text_to_music_prompt,
311
- )
312
-
313
- _history.append([query, final_content])
314
-
315
- # Generate final preview
316
- preview_val = generate_preview(final_content, language)
317
-
318
- yield {
319
- code_output: final_content,
320
- history: _history,
321
- sandbox: preview_val,
322
- history_output: history_to_chatbot_messages(_history),
323
- }
324
-
325
- except Exception as e:
326
- error_message = f"Error: {str(e)}"
327
- yield {
328
- code_output: error_message,
329
- history_output: history_to_chatbot_messages(_history),
330
- }
331
-
332
- def create_advanced_ui():
333
- """Create the advanced professional UI"""
334
-
335
- # Load saved theme
336
- current_theme_name = get_saved_theme()
337
- current_theme = THEME_CONFIGS[current_theme_name]["theme"]
338
-
339
- # Custom CSS for professional styling
340
- custom_css = """
341
- /* Professional styling */
342
- .gradio-container {
343
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif !important;
344
- }
345
-
346
- /* Advanced sidebar styling */
347
- .advanced-sidebar {
348
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
349
- border-radius: 16px;
350
- padding: 24px;
351
- margin-bottom: 16px;
352
- }
353
-
354
- .advanced-sidebar h3 {
355
- color: white;
356
- font-weight: 600;
357
- margin-bottom: 16px;
358
- font-size: 18px;
359
- }
360
-
361
- /* Model cards */
362
- .model-card {
363
- background: rgba(255, 255, 255, 0.1);
364
- backdrop-filter: blur(10px);
365
- border-radius: 12px;
366
- padding: 16px;
367
- margin-bottom: 12px;
368
- border: 1px solid rgba(255, 255, 255, 0.2);
369
- }
370
-
371
- .model-card.selected {
372
- background: rgba(255, 255, 255, 0.2);
373
- border-color: rgba(255, 255, 255, 0.4);
374
- }
375
-
376
- /* Demo cards */
377
- .demo-grid {
378
- display: grid;
379
- grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
380
- gap: 16px;
381
- margin: 20px 0;
382
- }
383
-
384
- .demo-card {
385
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
386
- border-radius: 12px;
387
- padding: 20px;
388
- cursor: pointer;
389
- transition: all 0.3s ease;
390
- border: 2px solid transparent;
391
- }
392
-
393
- .demo-card:hover {
394
- transform: translateY(-2px);
395
- box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15);
396
- border-color: #667eea;
397
- }
398
-
399
- .demo-card h4 {
400
- color: #2d3748;
401
- font-weight: 600;
402
- margin-bottom: 8px;
403
- }
404
-
405
- .demo-card p {
406
- color: #4a5568;
407
- font-size: 14px;
408
- line-height: 1.5;
409
- }
410
-
411
- .demo-category {
412
- display: inline-block;
413
- background: #667eea;
414
- color: white;
415
- padding: 4px 8px;
416
- border-radius: 12px;
417
- font-size: 12px;
418
- font-weight: 500;
419
- margin-bottom: 8px;
420
- }
421
-
422
- /* Feature toggles */
423
- .feature-toggle {
424
- background: rgba(103, 126, 234, 0.1);
425
- border: 1px solid rgba(103, 126, 234, 0.3);
426
- border-radius: 8px;
427
- padding: 12px;
428
- margin-bottom: 8px;
429
- }
430
-
431
- /* Status indicators */
432
- .status-indicator {
433
- display: inline-flex;
434
- align-items: center;
435
- gap: 8px;
436
- font-size: 14px;
437
- color: #4a5568;
438
- }
439
-
440
- .status-dot {
441
- width: 8px;
442
- height: 8px;
443
- border-radius: 50%;
444
- background: #48bb78;
445
- }
446
-
447
- .status-dot.warning {
448
- background: #ed8936;
449
- }
450
-
451
- .status-dot.error {
452
- background: #f56565;
453
- }
454
-
455
- /* Code editor enhancements */
456
- .code-editor-wrapper {
457
- border-radius: 8px;
458
- overflow: hidden;
459
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
460
- }
461
-
462
- /* Preview enhancements */
463
- .preview-container {
464
- border-radius: 8px;
465
- overflow: hidden;
466
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
467
- background: white;
468
- }
469
-
470
- /* Deployment section */
471
- .deployment-section {
472
- background: linear-gradient(135deg, #84fab0 0%, #8fd3f4 100%);
473
- border-radius: 12px;
474
- padding: 20px;
475
- margin-top: 16px;
476
- }
477
-
478
- .deployment-section h4 {
479
- color: #2d3748;
480
- font-weight: 600;
481
- margin-bottom: 12px;
482
- }
483
- """
484
-
485
- # Create the main interface
486
- with gr.Blocks(
487
- title="AnyCoder - Advanced AI Code Generator",
488
- theme=current_theme,
489
- css=custom_css
490
- ) as demo:
491
-
492
- # State management
493
- history = gr.State([])
494
- setting = gr.State({"system": from config import HTML_SYSTEM_PROMPT})
495
- current_model = gr.State(DEFAULT_MODEL)
496
-
497
- # Header
498
- with gr.Row():
499
- with gr.Column(scale=1):
500
- gr.HTML("""
501
- <div style='text-align: center; padding: 20px 0;'>
502
- <h1 style='font-size: 2.5em; font-weight: 700; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; margin-bottom: 8px;'>
503
- AnyCoder Pro
504
- </h1>
505
- <p style='font-size: 1.1em; color: #4a5568; margin: 0;'>
506
- Professional AI-Powered Code Generation Platform
507
- </p>
508
- </div>
509
- """)
510
-
511
- # Main layout
512
- with gr.Row():
513
- # Advanced Sidebar
514
- with gr.Column(scale=1, elem_classes=["advanced-sidebar"]) as sidebar:
515
- # Login section
516
- login_button = gr.LoginButton()
517
-
518
- # Model selection with categories
519
- with gr.Accordion("🤖 Model Selection", open=True):
520
- # Group models by category
521
- model_categories = {}
522
- for model in AVAILABLE_MODELS:
523
- category = model.get("category", "General")
524
- if category not in model_categories:
525
- model_categories[category] = []
526
- model_categories[category].append(model)
527
-
528
- model_dropdown = gr.Dropdown(
529
- choices=[model['name'] for model in AVAILABLE_MODELS],
530
- value=DEFAULT_MODEL['name'],
531
- label="Select Model",
532
- info="Choose the AI model for code generation"
533
- )
534
-
535
- # Model info display
536
- model_info = gr.Markdown(DEFAULT_MODEL['description'])
537
-
538
- # Project management
539
- with gr.Accordion("📁 Project Management", open=False):
540
- gr.Markdown("**Import Existing Project**")
541
- load_project_url = gr.Textbox(
542
- label="Project URL",
543
- placeholder="https://huggingface.co/spaces/user/space",
544
- info="Import from HF Spaces, GitHub, or HF Models"
545
- )
546
- load_project_btn = gr.Button("Import Project", variant="secondary")
547
- load_project_status = gr.Markdown(visible=False)
548
-
549
- # Code generation settings
550
- with gr.Accordion("⚙️ Generation Settings", open=True):
551
- language_dropdown = gr.Dropdown(
552
- choices=["html", "streamlit", "gradio", "python", "transformers.js", "svelte"],
553
- value="html",
554
- label="Framework/Language",
555
- info="Select the target framework"
556
- )
557
-
558
- enable_search = gr.Checkbox(
559
- label="🔍 Web Search Enhancement",
560
- value=False,
561
- info="Use real-time web search for up-to-date information"
562
- )
563
-
564
- if tavily_client:
565
- search_status = gr.HTML("""
566
- <div class="status-indicator">
567
- <div class="status-dot"></div>
568
- <span>Web search available</span>
569
- </div>
570
- """)
571
- else:
572
- search_status = gr.HTML("""
573
- <div class="status-indicator">
574
- <div class="status-dot error"></div>
575
- <span>Web search unavailable</span>
576
- </div>
577
- """)
578
-
579
- # Media generation features
580
- with gr.Accordion("🎨 AI Media Generation", open=False):
581
- enable_image_generation = gr.Checkbox(
582
- label="Generate Images (Text → Image)",
583
- value=False,
584
- info="Auto-generate images using Qwen-Image"
585
- )
586
-
587
- text_to_image_prompt = gr.Textbox(
588
- label="Image Generation Prompt",
589
- placeholder="Describe the image to generate...",
590
- lines=2,
591
- visible=False
592
- )
593
-
594
- enable_image_to_image = gr.Checkbox(
595
- label="Transform Images (Image → Image)",
596
- value=False,
597
- info="Transform uploaded images using AI"
598
- )
599
-
600
- image_to_image_prompt = gr.Textbox(
601
- label="Image Transformation Prompt",
602
- placeholder="Describe how to transform the image...",
603
- lines=2,
604
- visible=False
605
- )
606
-
607
- enable_image_to_video = gr.Checkbox(
608
- label="Generate Videos (Image → Video)",
609
- value=False,
610
- info="Create videos from uploaded images"
611
- )
612
-
613
- enable_text_to_video = gr.Checkbox(
614
- label="Generate Videos (Text → Video)",
615
- value=False,
616
- info="Create videos from text descriptions"
617
- )
618
-
619
- enable_text_to_music = gr.Checkbox(
620
- label="Generate Music (Text → Music)",
621
- value=False,
622
- info="Compose music from text descriptions"
623
- )
624
-
625
- # Input section
626
- with gr.Accordion("📝 Input & Files", open=True):
627
- user_input = gr.Textbox(
628
- label="What would you like to build?",
629
- placeholder="Describe your application in detail...",
630
- lines=4,
631
- info="Be specific about features, design, and functionality"
632
- )
633
-
634
- website_url_input = gr.Textbox(
635
- label="Website URL (for redesign)",
636
- placeholder="https://example.com",
637
- info="URL of website to redesign"
638
- )
639
-
640
- file_input = gr.File(
641
- label="Reference Files",
642
- file_types=[".pdf", ".txt", ".md", ".csv", ".docx", ".jpg", ".png"],
643
- info="Upload reference documents or images"
644
- )
645
-
646
- vlm_image = gr.Image(
647
- label="Design Reference Image",
648
- visible=False,
649
- info="Upload UI mockup or design reference"
650
- )
651
-
652
- generation_image = gr.Image(
653
- label="Image for Generation",
654
- visible=False,
655
- info="Upload image for AI processing"
656
- )
657
-
658
- # Action buttons
659
- with gr.Row():
660
- generate_btn = gr.Button("🚀 Generate", variant="primary", scale=2)
661
- clear_btn = gr.Button("🗑️ Clear", variant="secondary", scale=1)
662
-
663
- # Main content area
664
- with gr.Column(scale=3):
665
- # Quick start section
666
- with gr.Row():
667
- gr.HTML("""
668
- <div style='background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); border-radius: 12px; padding: 20px; margin-bottom: 20px;'>
669
- <h3 style='color: white; margin: 0 0 16px 0; font-weight: 600;'>Quick Start Examples</h3>
670
- <div class='demo-grid'>
671
- """)
672
-
673
- # Demo cards
674
- demo_cards = []
675
- for i, demo in enumerate(DEMO_LIST[:6]): # Show first 6 demos
676
- demo_card = gr.Button(
677
- f"""
678
- <div class='demo-card'>
679
- <div class='demo-category'>{demo.get('category', 'General')}</div>
680
- <h4>{demo['title']}</h4>
681
- <p>{demo['description']}</p>
682
- </div>
683
- """,
684
- variant="secondary",
685
- elem_classes=["demo-card-btn"]
686
- )
687
- demo_cards.append(demo_card)
688
-
689
- gr.HTML("</div></div>")
690
-
691
- # Main tabs
692
- with gr.Tabs() as main_tabs:
693
- # Preview tab
694
- with gr.Tab("🖥️ Live Preview"):
695
- sandbox = gr.HTML(
696
- label="Live Preview",
697
- elem_classes=["preview-container"]
698
- )
699
-
700
- # Code editor tab
701
- with gr.Tab("📝 Code Editor"):
702
- with gr.Row():
703
- with gr.Column():
704
- code_output = gr.Code(
705
- language="html",
706
- lines=30,
707
- interactive=True,
708
- label="Generated Code",
709
- elem_classes=["code-editor-wrapper"]
710
- )
711
-
712
- # Multi-file editors (hidden by default)
713
- with gr.Group(visible=False) as transformers_group:
714
- with gr.Tabs():
715
- with gr.Tab("index.html"):
716
- tjs_html_code = gr.Code(language="html", lines=25, interactive=True)
717
- with gr.Tab("index.js"):
718
- tjs_js_code = gr.Code(language="javascript", lines=25, interactive=True)
719
- with gr.Tab("style.css"):
720
- tjs_css_code = gr.Code(language="css", lines=25, interactive=True)
721
-
722
- # Deployment section
723
- with gr.Group(elem_classes=["deployment-section"], visible=False) as deployment_section:
724
- gr.Markdown("### 🚀 Deploy Your Application")
725
-
726
- with gr.Row():
727
- space_name_input = gr.Textbox(
728
- label="App Name",
729
- placeholder="my-awesome-app",
730
- scale=2
731
- )
732
-
733
- sdk_dropdown = gr.Dropdown(
734
- choices=["Static (HTML)", "Gradio (Python)", "Streamlit (Python)", "Transformers.js", "Svelte"],
735
- value="Static (HTML)",
736
- label="App Type",
737
- scale=1
738
- )
739
-
740
- with gr.Row():
741
- deploy_btn = gr.Button("🚀 Deploy to Spaces", variant="primary", scale=2)
742
- deploy_status = gr.Markdown("", scale=3)
743
-
744
- # Hidden components for state management
745
- history_output = gr.Chatbot(visible=False, type="messages")
746
-
747
- # Event handlers
748
- def on_model_change(model_name):
749
- for m in AVAILABLE_MODELS:
750
- if m['name'] == model_name:
751
- return m, gr.update(value=m['description']), update_image_input_visibility(m)
752
- return AVAILABLE_MODELS[0], gr.update(value=AVAILABLE_MODELS[0]['description']), gr.update(visible=False)
753
-
754
- def on_demo_click(demo_index):
755
- if 0 <= demo_index < len(DEMO_LIST):
756
- return DEMO_LIST[demo_index]['description']
757
- return ""
758
-
759
- def toggle_media_prompts(image_gen, img2img, img2vid, txt2vid, txt2music):
760
- return [
761
- gr.update(visible=image_gen), # text_to_image_prompt
762
- gr.update(visible=img2img), # image_to_image_prompt
763
- gr.update(visible=img2img or img2vid), # generation_image
764
- ]
765
-
766
- def show_deployment_section():
767
- return gr.update(visible=True)
768
-
769
- def handle_import_project(url):
770
- if not url.strip():
771
- return gr.update(value="Please enter a URL.", visible=True), "", ""
772
-
773
- status, code = load_project_from_url(url)
774
- return gr.update(value=status, visible=True), code, gr.update(value="", visible=False)
775
-
776
- # Wire up events
777
- model_dropdown.change(
778
- on_model_change,
779
- inputs=[model_dropdown],
780
- outputs=[current_model, model_info, vlm_image]
781
- )
782
-
783
- # Demo card clicks
784
- for i, card in enumerate(demo_cards):
785
- card.click(
786
- lambda idx=i: on_demo_click(idx),
787
- outputs=[user_input]
788
- )
789
-
790
- # Media generation toggles
791
- for toggle in [enable_image_generation, enable_image_to_image, enable_image_to_video]:
792
- toggle.change(
793
- toggle_media_prompts,
794
- inputs=[enable_image_generation, enable_image_to_image, enable_image_to_video, enable_text_to_video, enable_text_to_music],
795
- outputs=[text_to_image_prompt, image_to_image_prompt, generation_image]
796
- )
797
-
798
- # Main generation
799
- generate_btn.click(
800
- generation_code,
801
- inputs=[
802
- user_input, vlm_image, generation_image, file_input, website_url_input,
803
- setting, history, current_model, enable_search, language_dropdown,
804
- gr.State("auto"), enable_image_generation, enable_image_to_image,
805
- image_to_image_prompt, text_to_image_prompt, enable_image_to_video,
806
- gr.State(None), enable_text_to_video, gr.State(None), enable_text_to_music, gr.State(None)
807
- ],
808
- outputs=[code_output, history, sandbox, history_output]
809
- ).then(
810
- show_deployment_section,
811
- outputs=[deployment_section]
812
- )
813
-
814
- # Project import
815
- load_project_btn.click(
816
- handle_import_project,
817
- inputs=[load_project_url],
818
- outputs=[load_project_status, code_output, load_project_url]
819
- )
820
-
821
- # Clear functionality
822
- clear_btn.click(
823
- clear_history,
824
- outputs=[history, history_output, file_input, website_url_input]
825
- )
826
-
827
- # Deployment
828
- deploy_btn.click(
829
- deploy_to_user_space,
830
- inputs=[code_output, space_name_input, sdk_dropdown],
831
- outputs=[deploy_status]
832
- )
833
-
834
- return demo
835
-
836
- # Main application entry point
837
- if __name__ == "__main__":
838
- # Clean up any orphaned temporary files
839
- cleanup_all_temp_media()
840
-
841
- # Create and launch the application
842
- demo = create_advanced_ui()
843
- demo.queue(api_open=False, default_concurrency_limit=20).launch(
844
- show_api=False,
845
- server_name="0.0.0.0",
846
- server_port=7860,
847
- ssr_mode=True
848
- )