akhaliq HF Staff commited on
Commit
18dcd5e
·
1 Parent(s): b7e5bf3

add qwen image

Browse files
Files changed (1) hide show
  1. app.py +361 -9
app.py CHANGED
@@ -872,6 +872,191 @@ def process_image_for_model(image):
872
  img_str = base64.b64encode(buffer.getvalue()).decode()
873
  return f"data:image/png;base64,{img_str}"
874
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
875
  def create_multimodal_message(text, image=None):
876
  """Create a multimodal message with text and optional image"""
877
  if image is None:
@@ -1544,7 +1729,7 @@ The HTML code above contains the complete original website structure with all im
1544
  stop_generation = False
1545
 
1546
 
1547
- def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optional[str], website_url: Optional[str], _setting: Dict[str, str], _history: Optional[History], _current_model: Dict, enable_search: bool = False, language: str = "html", provider: str = "auto"):
1548
  if query is None:
1549
  query = ''
1550
  if _history is None:
@@ -1660,11 +1845,29 @@ This will help me create a better design for you."""
1660
  content = f"Error with GLM-4.5: {str(e)}\n\nPlease make sure HF_TOKEN environment variable is set."
1661
 
1662
  clean_code = remove_code_block(content)
1663
- _history.append([query, content])
 
 
 
 
 
 
 
 
 
 
1664
 
1665
  if language == "transformers.js":
1666
  files = parse_transformers_js_output(clean_code)
1667
  if files['index.html'] and files['index.js'] and files['style.css']:
 
 
 
 
 
 
 
 
1668
  formatted_output = format_transformers_js_output(files)
1669
  yield {
1670
  code_output: formatted_output,
@@ -1682,6 +1885,107 @@ This will help me create a better design for you."""
1682
  elif language == "svelte":
1683
  files = parse_svelte_output(clean_code)
1684
  if files['src/App.svelte'] and files['src/app.css']:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1685
  formatted_output = format_svelte_output(files)
1686
  yield {
1687
  code_output: formatted_output,
@@ -1701,6 +2005,15 @@ This will help me create a better design for you."""
1701
  last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
1702
  modified_content = apply_search_replace_changes(last_content, clean_code)
1703
  clean_content = remove_code_block(modified_content)
 
 
 
 
 
 
 
 
 
1704
  yield {
1705
  code_output: clean_content,
1706
  history: _history,
@@ -1708,10 +2021,19 @@ This will help me create a better design for you."""
1708
  history_output: history_to_chatbot_messages(_history),
1709
  }
1710
  else:
 
 
 
 
 
 
 
 
 
1711
  yield {
1712
- code_output: clean_code,
1713
  history: _history,
1714
- sandbox: send_to_sandbox(clean_code) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
1715
  history_output: history_to_chatbot_messages(_history),
1716
  }
1717
  return
@@ -1908,6 +2230,15 @@ This will help me create a better design for you."""
1908
  last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
1909
  modified_content = apply_search_replace_changes(last_content, final_code)
1910
  clean_content = remove_code_block(modified_content)
 
 
 
 
 
 
 
 
 
1911
  # Update history with the cleaned content
1912
  _history.append([query, clean_content])
1913
  yield {
@@ -1918,11 +2249,21 @@ This will help me create a better design for you."""
1918
  }
1919
  else:
1920
  # Regular generation - use the content as is
1921
- _history.append([query, content])
 
 
 
 
 
 
 
 
 
 
1922
  yield {
1923
- code_output: remove_code_block(content),
1924
  history: _history,
1925
- sandbox: send_to_sandbox(remove_code_block(content)),
1926
  history_output: history_to_chatbot_messages(_history),
1927
  }
1928
  except Exception as e:
@@ -2725,6 +3066,13 @@ with gr.Blocks(
2725
  value=False,
2726
  visible=True
2727
  )
 
 
 
 
 
 
 
2728
  model_dropdown = gr.Dropdown(
2729
  choices=[model['name'] for model in AVAILABLE_MODELS],
2730
  value="Qwen3-Coder-480B-A35B-Instruct",
@@ -2894,7 +3242,7 @@ with gr.Blocks(
2894
 
2895
  btn.click(
2896
  generation_code,
2897
- inputs=[input, image_input, file_input, website_url_input, setting, history, current_model, search_toggle, language_dropdown, provider_state],
2898
  outputs=[code_output, history, sandbox, history_output]
2899
  ).then(
2900
  show_deploy_components,
@@ -3435,4 +3783,8 @@ with gr.Blocks(
3435
  # Optionally, you can keep the old deploy_btn.click for the default method as a secondary button.
3436
 
3437
  if __name__ == "__main__":
3438
- demo.queue(api_open=False, default_concurrency_limit=20).launch(show_api=False, ssr_mode=True, mcp_server=False)
 
 
 
 
 
872
  img_str = base64.b64encode(buffer.getvalue()).decode()
873
  return f"data:image/png;base64,{img_str}"
874
 
875
+ def generate_image_with_qwen(prompt: str, image_index: int = 0) -> str:
876
+ """Generate image using Qwen image model via Hugging Face InferenceClient with optimized data URL"""
877
+ try:
878
+ # Check if HF_TOKEN is available
879
+ if not os.getenv('HF_TOKEN'):
880
+ return "Error: HF_TOKEN environment variable is not set. Please set it to your Hugging Face API token."
881
+
882
+ # Create InferenceClient for Qwen image generation
883
+ client = InferenceClient(
884
+ provider="auto",
885
+ api_key=os.getenv('HF_TOKEN'),
886
+ bill_to="huggingface",
887
+ )
888
+
889
+ # Generate image using Qwen/Qwen-Image model
890
+ image = client.text_to_image(
891
+ prompt,
892
+ model="Qwen/Qwen-Image",
893
+ )
894
+
895
+ # Resize image to reduce size while maintaining quality
896
+ max_size = 512
897
+ if image.width > max_size or image.height > max_size:
898
+ image.thumbnail((max_size, max_size), Image.Resampling.LANCZOS)
899
+
900
+ # Convert PIL Image to optimized base64 for HTML embedding
901
+ import io
902
+ import base64
903
+
904
+ buffer = io.BytesIO()
905
+ # Save as JPEG with compression for smaller file size
906
+ image.convert('RGB').save(buffer, format='JPEG', quality=85, optimize=True)
907
+ img_str = base64.b64encode(buffer.getvalue()).decode()
908
+
909
+ # Return HTML img tag with optimized data URL
910
+ return f'<img src="data:image/jpeg;base64,{img_str}" alt="{prompt}" style="max-width: 100%; height: auto; border-radius: 8px; margin: 10px 0;" loading="lazy" />'
911
+
912
+ except Exception as e:
913
+ print(f"Image generation error: {str(e)}")
914
+ return f"Error generating image: {str(e)}"
915
+
916
+ def extract_image_prompts_from_text(text: str, num_images_needed: int = 1) -> list:
917
+ """Extract image generation prompts from the full text based on number of images needed"""
918
+ # Use the entire text as the base prompt for image generation
919
+ # Clean up the text and create variations for the required number of images
920
+
921
+ # Clean the text
922
+ cleaned_text = text.strip()
923
+ if not cleaned_text:
924
+ return []
925
+
926
+ # Create variations of the prompt for the required number of images
927
+ prompts = []
928
+
929
+ # Generate exactly the number of images needed
930
+ for i in range(num_images_needed):
931
+ if i == 0:
932
+ # First image: Use the full prompt as-is
933
+ prompts.append(cleaned_text)
934
+ elif i == 1:
935
+ # Second image: Add "visual representation" to make it more image-focused
936
+ prompts.append(f"Visual representation of {cleaned_text}")
937
+ elif i == 2:
938
+ # Third image: Add "illustration" to create a different style
939
+ prompts.append(f"Illustration of {cleaned_text}")
940
+ else:
941
+ # For additional images, use different variations
942
+ variations = [
943
+ f"Digital art of {cleaned_text}",
944
+ f"Modern design of {cleaned_text}",
945
+ f"Professional illustration of {cleaned_text}",
946
+ f"Clean design of {cleaned_text}",
947
+ f"Beautiful visualization of {cleaned_text}",
948
+ f"Stylish representation of {cleaned_text}",
949
+ f"Contemporary design of {cleaned_text}",
950
+ f"Elegant illustration of {cleaned_text}"
951
+ ]
952
+ variation_index = (i - 3) % len(variations)
953
+ prompts.append(variations[variation_index])
954
+
955
+ return prompts
956
+
957
+ def create_image_replacement_blocks(html_content: str, user_prompt: str) -> str:
958
+ """Create search/replace blocks to replace placeholder images with generated Qwen images"""
959
+ if not user_prompt:
960
+ return ""
961
+
962
+ # Find existing image placeholders in the HTML first
963
+ import re
964
+
965
+ # Common patterns for placeholder images
966
+ placeholder_patterns = [
967
+ r'<img[^>]*src=["\'](?:placeholder|dummy|sample|example)[^"\']*["\'][^>]*>',
968
+ r'<img[^>]*src=["\']https?://via\.placeholder\.com[^"\']*["\'][^>]*>',
969
+ r'<img[^>]*src=["\']https?://picsum\.photos[^"\']*["\'][^>]*>',
970
+ r'<img[^>]*src=["\']https?://dummyimage\.com[^"\']*["\'][^>]*>',
971
+ r'<img[^>]*alt=["\'][^"\']*placeholder[^"\']*["\'][^>]*>',
972
+ r'<img[^>]*class=["\'][^"\']*placeholder[^"\']*["\'][^>]*>',
973
+ r'<img[^>]*id=["\'][^"\']*placeholder[^"\']*["\'][^>]*>',
974
+ r'<img[^>]*src=["\']data:image[^"\']*["\'][^>]*>', # Base64 images
975
+ r'<img[^>]*src=["\']#["\'][^>]*>', # Empty src
976
+ r'<img[^>]*src=["\']about:blank["\'][^>]*>', # About blank
977
+ ]
978
+
979
+ # Find all placeholder images
980
+ placeholder_images = []
981
+ for pattern in placeholder_patterns:
982
+ matches = re.findall(pattern, html_content, re.IGNORECASE)
983
+ placeholder_images.extend(matches)
984
+
985
+ # If no placeholder images found, look for any img tags
986
+ if not placeholder_images:
987
+ img_pattern = r'<img[^>]*>'
988
+ placeholder_images = re.findall(img_pattern, html_content)
989
+
990
+ # Also look for div elements that might be image placeholders
991
+ div_placeholder_patterns = [
992
+ r'<div[^>]*class=["\'][^"\']*(?:image|img|photo|picture)[^"\']*["\'][^>]*>.*?</div>',
993
+ r'<div[^>]*id=["\'][^"\']*(?:image|img|photo|picture)[^"\']*["\'][^>]*>.*?</div>',
994
+ ]
995
+
996
+ for pattern in div_placeholder_patterns:
997
+ matches = re.findall(pattern, html_content, re.IGNORECASE | re.DOTALL)
998
+ placeholder_images.extend(matches)
999
+
1000
+ # Count how many images we need to generate
1001
+ num_images_needed = len(placeholder_images)
1002
+
1003
+ if num_images_needed == 0:
1004
+ return ""
1005
+
1006
+ # Generate image prompts based on the number of images found
1007
+ image_prompts = extract_image_prompts_from_text(user_prompt, num_images_needed)
1008
+
1009
+ # Generate images for each prompt
1010
+ generated_images = []
1011
+ for i, prompt in enumerate(image_prompts):
1012
+ image_html = generate_image_with_qwen(prompt, i)
1013
+ if not image_html.startswith("Error"):
1014
+ generated_images.append((i, image_html))
1015
+
1016
+ if not generated_images:
1017
+ return ""
1018
+
1019
+ # Create search/replace blocks
1020
+ replacement_blocks = []
1021
+
1022
+ for i, (prompt_index, generated_image) in enumerate(generated_images):
1023
+ if i < len(placeholder_images):
1024
+ # Replace existing placeholder
1025
+ placeholder = placeholder_images[i]
1026
+ # Clean up the placeholder for better matching
1027
+ placeholder_clean = re.sub(r'\s+', ' ', placeholder.strip())
1028
+
1029
+ # Try multiple variations of the placeholder for better matching
1030
+ placeholder_variations = [
1031
+ placeholder_clean,
1032
+ placeholder_clean.replace('"', "'"),
1033
+ placeholder_clean.replace("'", '"'),
1034
+ re.sub(r'\s+', ' ', placeholder_clean),
1035
+ placeholder_clean.replace(' ', ' '),
1036
+ ]
1037
+
1038
+ # Create a replacement block for each variation
1039
+ for variation in placeholder_variations:
1040
+ replacement_blocks.append(f"""{SEARCH_START}
1041
+ {variation}
1042
+ {DIVIDER}
1043
+ {generated_image}
1044
+ {REPLACE_END}""")
1045
+ else:
1046
+ # Add new image if we have more generated images than placeholders
1047
+ # Find a good insertion point (after body tag or main content)
1048
+ if '<body' in html_content:
1049
+ body_end = html_content.find('>', html_content.find('<body')) + 1
1050
+ insertion_point = html_content[:body_end] + '\n '
1051
+ replacement_blocks.append(f"""{SEARCH_START}
1052
+ {insertion_point}
1053
+ {DIVIDER}
1054
+ {insertion_point}
1055
+ {generated_image}
1056
+ {REPLACE_END}""")
1057
+
1058
+ return '\n\n'.join(replacement_blocks)
1059
+
1060
  def create_multimodal_message(text, image=None):
1061
  """Create a multimodal message with text and optional image"""
1062
  if image is None:
 
1729
  stop_generation = False
1730
 
1731
 
1732
+ def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optional[str], website_url: Optional[str], _setting: Dict[str, str], _history: Optional[History], _current_model: Dict, enable_search: bool = False, language: str = "html", provider: str = "auto", enable_image_generation: bool = False):
1733
  if query is None:
1734
  query = ''
1735
  if _history is None:
 
1845
  content = f"Error with GLM-4.5: {str(e)}\n\nPlease make sure HF_TOKEN environment variable is set."
1846
 
1847
  clean_code = remove_code_block(content)
1848
+
1849
+ # Apply image generation if enabled and this is HTML content
1850
+ final_content = content
1851
+ if enable_image_generation and language == "html" and (clean_code.strip().startswith('<!DOCTYPE html>') or clean_code.strip().startswith('<html')):
1852
+ # Create search/replace blocks for image replacement based on images found in code
1853
+ image_replacement_blocks = create_image_replacement_blocks(content, query)
1854
+ if image_replacement_blocks:
1855
+ # Apply the image replacements using existing search/replace logic
1856
+ final_content = apply_search_replace_changes(content, image_replacement_blocks)
1857
+
1858
+ _history.append([query, final_content])
1859
 
1860
  if language == "transformers.js":
1861
  files = parse_transformers_js_output(clean_code)
1862
  if files['index.html'] and files['index.js'] and files['style.css']:
1863
+ # Apply image generation if enabled
1864
+ if enable_image_generation:
1865
+ # Create search/replace blocks for image replacement based on images found in code
1866
+ image_replacement_blocks = create_image_replacement_blocks(files['index.html'], query)
1867
+ if image_replacement_blocks:
1868
+ # Apply the image replacements using existing search/replace logic
1869
+ files['index.html'] = apply_search_replace_changes(files['index.html'], image_replacement_blocks)
1870
+
1871
  formatted_output = format_transformers_js_output(files)
1872
  yield {
1873
  code_output: formatted_output,
 
1885
  elif language == "svelte":
1886
  files = parse_svelte_output(clean_code)
1887
  if files['src/App.svelte'] and files['src/app.css']:
1888
+ # Apply image generation if enabled (add image generation logic to Svelte)
1889
+ if enable_image_generation:
1890
+ # For Svelte, we'll add a script section that generates images dynamically
1891
+ # This is more appropriate for Svelte than trying to inject static images
1892
+ image_generation_script = """
1893
+ <script>
1894
+ import { onMount } from 'svelte';
1895
+
1896
+ let generatedImages = [];
1897
+
1898
+ onMount(async () => {
1899
+ // Generate images using Qwen API based on the user prompt
1900
+ const userPrompt = """ + repr(query) + """;
1901
+
1902
+ // Create variations for multiple images
1903
+ const imagePrompts = [
1904
+ userPrompt,
1905
+ `Visual representation of ${userPrompt}`,
1906
+ `Illustration of ${userPrompt}`
1907
+ ];
1908
+
1909
+ for (const prompt of imagePrompts) {
1910
+ try {
1911
+ // This would need to be implemented with actual API calls
1912
+ // For now, we'll create placeholder elements
1913
+ generatedImages = [...generatedImages, {
1914
+ prompt: prompt,
1915
+ src: `data:image/svg+xml;base64,${btoa('<svg xmlns="http://www.w3.org/2000/svg" width="300" height="200"><rect width="100%" height="100%" fill="#f0f0f0"/><text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="#666">Generated: ${prompt}</text></svg>')}`,
1916
+ alt: prompt
1917
+ }];
1918
+ } catch (error) {
1919
+ console.error('Error generating image:', error);
1920
+ }
1921
+ }
1922
+ });
1923
+ </script>
1924
+
1925
+ <!-- Generated Images Section -->
1926
+ {#if generatedImages.length > 0}
1927
+ <div class="generated-images">
1928
+ <h3>Generated Images</h3>
1929
+ <div class="image-grid">
1930
+ {#each generatedImages as image}
1931
+ <img src={image.src} alt={image.alt} style="max-width: 100%; height: auto; border-radius: 8px; margin: 10px 0;" />
1932
+ {/each}
1933
+ </div>
1934
+ </div>
1935
+ {/if}"""
1936
+
1937
+ # Add the image generation script to App.svelte
1938
+ if '<script>' in files['src/App.svelte']:
1939
+ # Find the end of the script section and add after it
1940
+ script_end = files['src/App.svelte'].find('</script>') + 8
1941
+ files['src/App.svelte'] = files['src/App.svelte'][:script_end] + '\n' + image_generation_script + files['src/App.svelte'][script_end:]
1942
+ else:
1943
+ # Add script section at the beginning
1944
+ files['src/App.svelte'] = image_generation_script + '\n\n' + files['src/App.svelte']
1945
+
1946
+ # Add CSS for generated images
1947
+ image_css = """
1948
+ /* Generated Images Styling */
1949
+ .generated-images {
1950
+ margin: 20px 0;
1951
+ padding: 20px;
1952
+ background: #f8f9fa;
1953
+ border-radius: 8px;
1954
+ border: 1px solid #e9ecef;
1955
+ }
1956
+
1957
+ .generated-images h3 {
1958
+ margin: 0 0 15px 0;
1959
+ color: #495057;
1960
+ font-size: 1.2em;
1961
+ }
1962
+
1963
+ .image-grid {
1964
+ display: grid;
1965
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
1966
+ gap: 15px;
1967
+ align-items: start;
1968
+ }
1969
+
1970
+ .image-grid img {
1971
+ width: 100%;
1972
+ height: auto;
1973
+ border-radius: 8px;
1974
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
1975
+ transition: transform 0.2s ease;
1976
+ }
1977
+
1978
+ .image-grid img:hover {
1979
+ transform: scale(1.02);
1980
+ }
1981
+ """
1982
+
1983
+ # Add CSS to app.css
1984
+ if files['src/app.css']:
1985
+ files['src/app.css'] += '\n' + image_css
1986
+ else:
1987
+ files['src/app.css'] = image_css
1988
+
1989
  formatted_output = format_svelte_output(files)
1990
  yield {
1991
  code_output: formatted_output,
 
2005
  last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
2006
  modified_content = apply_search_replace_changes(last_content, clean_code)
2007
  clean_content = remove_code_block(modified_content)
2008
+
2009
+ # Apply image generation if enabled and this is HTML content
2010
+ if enable_image_generation and language == "html" and (clean_content.strip().startswith('<!DOCTYPE html>') or clean_content.strip().startswith('<html')):
2011
+ # Create search/replace blocks for image replacement based on images found in code
2012
+ image_replacement_blocks = create_image_replacement_blocks(clean_content, query)
2013
+ if image_replacement_blocks:
2014
+ # Apply the image replacements using existing search/replace logic
2015
+ clean_content = apply_search_replace_changes(clean_content, image_replacement_blocks)
2016
+
2017
  yield {
2018
  code_output: clean_content,
2019
  history: _history,
 
2021
  history_output: history_to_chatbot_messages(_history),
2022
  }
2023
  else:
2024
+ # Apply image generation if enabled and this is HTML content
2025
+ final_content = clean_code
2026
+ if enable_image_generation and language == "html" and (final_content.strip().startswith('<!DOCTYPE html>') or final_content.strip().startswith('<html')):
2027
+ # Create search/replace blocks for image replacement based on images found in code
2028
+ image_replacement_blocks = create_image_replacement_blocks(final_content, query)
2029
+ if image_replacement_blocks:
2030
+ # Apply the image replacements using existing search/replace logic
2031
+ final_content = apply_search_replace_changes(final_content, image_replacement_blocks)
2032
+
2033
  yield {
2034
+ code_output: final_content,
2035
  history: _history,
2036
+ sandbox: send_to_sandbox(final_content) if language == "html" else "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your code using the download button above.</div>",
2037
  history_output: history_to_chatbot_messages(_history),
2038
  }
2039
  return
 
2230
  last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
2231
  modified_content = apply_search_replace_changes(last_content, final_code)
2232
  clean_content = remove_code_block(modified_content)
2233
+
2234
+ # Apply image generation if enabled and this is HTML content
2235
+ if enable_image_generation and language == "html" and (clean_content.strip().startswith('<!DOCTYPE html>') or clean_content.strip().startswith('<html')):
2236
+ # Create search/replace blocks for image replacement based on images found in code
2237
+ image_replacement_blocks = create_image_replacement_blocks(clean_content, query)
2238
+ if image_replacement_blocks:
2239
+ # Apply the image replacements using existing search/replace logic
2240
+ clean_content = apply_search_replace_changes(clean_content, image_replacement_blocks)
2241
+
2242
  # Update history with the cleaned content
2243
  _history.append([query, clean_content])
2244
  yield {
 
2249
  }
2250
  else:
2251
  # Regular generation - use the content as is
2252
+ final_content = remove_code_block(content)
2253
+
2254
+ # Apply image generation if enabled and this is HTML content
2255
+ if enable_image_generation and language == "html" and (final_content.strip().startswith('<!DOCTYPE html>') or final_content.strip().startswith('<html')):
2256
+ # Create search/replace blocks for image replacement based on images found in code
2257
+ image_replacement_blocks = create_image_replacement_blocks(final_content, query)
2258
+ if image_replacement_blocks:
2259
+ # Apply the image replacements using existing search/replace logic
2260
+ final_content = apply_search_replace_changes(final_content, image_replacement_blocks)
2261
+
2262
+ _history.append([query, final_content])
2263
  yield {
2264
+ code_output: final_content,
2265
  history: _history,
2266
+ sandbox: send_to_sandbox(final_content),
2267
  history_output: history_to_chatbot_messages(_history),
2268
  }
2269
  except Exception as e:
 
3066
  value=False,
3067
  visible=True
3068
  )
3069
+ # Image generation toggle
3070
+ image_generation_toggle = gr.Checkbox(
3071
+ label="🎨 Generate Images",
3072
+ value=False,
3073
+ visible=True,
3074
+ info="Include generated images in your outputs using Qwen image model"
3075
+ )
3076
  model_dropdown = gr.Dropdown(
3077
  choices=[model['name'] for model in AVAILABLE_MODELS],
3078
  value="Qwen3-Coder-480B-A35B-Instruct",
 
3242
 
3243
  btn.click(
3244
  generation_code,
3245
+ inputs=[input, image_input, file_input, website_url_input, setting, history, current_model, search_toggle, language_dropdown, provider_state, image_generation_toggle],
3246
  outputs=[code_output, history, sandbox, history_output]
3247
  ).then(
3248
  show_deploy_components,
 
3783
  # Optionally, you can keep the old deploy_btn.click for the default method as a secondary button.
3784
 
3785
  if __name__ == "__main__":
3786
+ demo.queue(api_open=False, default_concurrency_limit=20).launch(
3787
+ show_api=False,
3788
+ ssr_mode=True,
3789
+ mcp_server=False
3790
+ )