CoolFace
Apppublic

sasivedi/anycoder

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
app.py2399 linesDownload Raw Back to root
1import os2import re3from http import HTTPStatus4from typing import Dict, List, Optional, Tuple5import base646import mimetypes7import PyPDF28import docx9import cv210import numpy as np11from PIL import Image12import pytesseract13import requests14from urllib.parse import urlparse, urljoin15from bs4 import BeautifulSoup16import html2text17import json18import time19import webbrowser20import urllib.parse21 22import gradio as gr23from huggingface_hub import InferenceClient24from tavily import TavilyClient25from huggingface_hub import HfApi26import tempfile27from openai import OpenAI28 29# Gradio supported languages for syntax highlighting30GRADIO_SUPPORTED_LANGUAGES = [31    "python", "c", "cpp", "markdown", "latex", "json", "html", "css", "javascript", "jinja2", "typescript", "yaml", "dockerfile", "shell", "r", "sql", "sql-msSQL", "sql-mySQL", "sql-mariaDB", "sql-sqlite", "sql-cassandra", "sql-plSQL", "sql-hive", "sql-pgSQL", "sql-gql", "sql-gpSQL", "sql-sparkSQL", "sql-esper", None32]33 34def get_gradio_language(language):35    return language if language in GRADIO_SUPPORTED_LANGUAGES else None36 37# Search/Replace Constants38SEARCH_START = "<<<<<<< SEARCH"39DIVIDER = "======="40REPLACE_END = ">>>>>>> REPLACE"41 42# Configuration43HTML_SYSTEM_PROMPT = """ONLY USE HTML, CSS AND JAVASCRIPT. If you want to use ICON make sure to import the library first. Try to create the best UI possible by using only HTML, CSS and JAVASCRIPT. MAKE IT RESPONSIVE USING MODERN CSS. Use as much as you can modern CSS for the styling, if you can't do something with modern CSS, then use custom CSS. Also, try to elaborate as much as you can, to create something unique. ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE44 45For website redesign tasks:46- Use the provided original HTML code as the starting point for redesign47- Preserve all original content, structure, and functionality48- Keep the same semantic HTML structure but enhance the styling49- Reuse all original images and their URLs from the HTML code50- Create a modern, responsive design with improved typography and spacing51- Use modern CSS frameworks and design patterns52- Ensure accessibility and mobile responsiveness53- Maintain the same navigation and user flow54- Enhance the visual design while keeping the original layout structure55 56If an image is provided, analyze it and use the visual information to better understand the user's requirements.57 58Always respond with code that can be executed or rendered directly.59 60Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text. Do NOT add the language name at the top of the code output."""61 62TRANSFORMERS_JS_SYSTEM_PROMPT = """You are an expert web developer creating a transformers.js application. You will generate THREE separate files: index.html, index.js, and style.css.63 64IMPORTANT: You MUST output ALL THREE files in the following format:65 66```html67<!-- index.html content here -->68```69 70```javascript71// index.js content here72```73 74```css75/* style.css content here */76```77 78Requirements:791. Create a modern, responsive web application using transformers.js802. Use the transformers.js library for AI/ML functionality813. Create a clean, professional UI with good user experience824. Make the application fully responsive for mobile devices835. Use modern CSS practices and JavaScript ES6+ features846. Include proper error handling and loading states857. Follow accessibility best practices86 87The index.html should contain the basic HTML structure and link to the CSS and JS files.88The index.js should contain all the JavaScript logic including transformers.js integration.89The style.css should contain all the styling for the application.90 91Always output only the three code blocks as shown above, and do not include any explanations or extra text."""92 93SVELTE_SYSTEM_PROMPT = """You are an expert Svelte developer creating a modern Svelte application. You will generate ONLY the custom files that need user-specific content.94 95IMPORTANT: You MUST output ONLY the custom files in the following format:96 97```svelte98<!-- src/App.svelte content here -->99```100 101```css102/* src/app.css content here */103```104 105```svelte106<!-- src/lib/Counter.svelte content here -->107```108 109Requirements:1101. Create a modern, responsive Svelte application1112. Use TypeScript for better type safety1123. Create a clean, professional UI with good user experience1134. Make the application fully responsive for mobile devices1145. Use modern CSS practices and Svelte best practices1156. Include proper error handling and loading states1167. Follow accessibility best practices1178. Use Svelte's reactive features effectively1189. Include proper component structure and organization119 120The files you generate are:121- src/App.svelte: Main application component (your custom app logic)122- src/app.css: Global styles (your custom styling)123- src/lib/Counter.svelte: Example component (your custom components)124 125The other files (index.html, package.json, vite.config.ts, tsconfig files, svelte.config.js, src/main.ts, src/vite-env.d.ts) are provided by the Svelte template and don't need to be generated.126 127Always output only the three code blocks as shown above, and do not include any explanations or extra text."""128 129SVELTE_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert Svelte developer creating a modern Svelte application. You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific Svelte technologies.130 131You will generate ONLY the custom files that need user-specific content.132 133IMPORTANT: You MUST output ONLY the custom files in the following format:134 135```svelte136<!-- src/App.svelte content here -->137```138 139```css140/* src/app.css content here */141```142 143```svelte144<!-- src/lib/Counter.svelte content here -->145```146 147Requirements:1481. Create a modern, responsive Svelte application1492. Use TypeScript for better type safety1503. Create a clean, professional UI with good user experience1514. Make the application fully responsive for mobile devices1525. Use modern CSS practices and Svelte best practices1536. Include proper error handling and loading states1547. Follow accessibility best practices1558. Use Svelte's reactive features effectively1569. Include proper component structure and organization15710. Use web search to find the latest Svelte patterns, libraries, and best practices158 159The files you generate are:160- src/App.svelte: Main application component (your custom app logic)161- src/app.css: Global styles (your custom styling)162- src/lib/Counter.svelte: Example component (your custom components)163 164The other files (index.html, package.json, vite.config.ts, tsconfig files, svelte.config.js, src/main.ts, src/vite-env.d.ts) are provided by the Svelte template and don't need to be generated.165 166Always output only the three code blocks as shown above, and do not include any explanations or extra text."""167 168TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert web developer creating a transformers.js application. You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies for transformers.js.169 170You will generate THREE separate files: index.html, index.js, and style.css.171 172IMPORTANT: You MUST output ALL THREE files in the following format:173 174```html175<!-- index.html content here -->176```177 178```javascript179// index.js content here180```181 182```css183/* style.css content here */184```185 186Requirements:1871. Create a modern, responsive web application using transformers.js1882. Use the transformers.js library for AI/ML functionality1893. Use web search to find current best practices and latest transformers.js features1904. Create a clean, professional UI with good user experience1915. Make the application fully responsive for mobile devices1926. Use modern CSS practices and JavaScript ES6+ features1937. Include proper error handling and loading states1948. Follow accessibility best practices195 196The index.html should contain the basic HTML structure and link to the CSS and JS files.197The index.js should contain all the JavaScript logic including transformers.js integration.198The style.css should contain all the styling for the application.199 200Always output only the three code blocks as shown above, and do not include any explanations or extra text."""201 202GENERIC_SYSTEM_PROMPT = """You are an expert {language} developer. Write clean, idiomatic, and runnable {language} code for the user's request. If possible, include comments and best practices. Output ONLY the code inside a ``` code block, and do not include any explanations or extra text. If the user provides a file or other context, use it as a reference. If the code is for a script or app, make it as self-contained as possible. Do NOT add the language name at the top of the code output."""203 204# System prompt with search capability205HTML_SYSTEM_PROMPT_WITH_SEARCH = """ONLY USE HTML, CSS AND JAVASCRIPT. If you want to use ICON make sure to import the library first. Try to create the best UI possible by using only HTML, CSS and JAVASCRIPT. MAKE IT RESPONSIVE USING MODERN CSS. Use as much as you can modern CSS for the styling, if you can't do something with modern CSS, then use custom CSS. Also, try to elaborate as much as you can, to create something unique. ALWAYS GIVE THE RESPONSE INTO A SINGLE HTML FILE206 207You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies.208 209For website redesign tasks:210- Use the provided original HTML code as the starting point for redesign211- Preserve all original content, structure, and functionality212- Keep the same semantic HTML structure but enhance the styling213- Reuse all original images and their URLs from the HTML code214- Use web search to find current design trends and best practices for the specific type of website215- Create a modern, responsive design with improved typography and spacing216- Use modern CSS frameworks and design patterns217- Ensure accessibility and mobile responsiveness218- Maintain the same navigation and user flow219- Enhance the visual design while keeping the original layout structure220 221If an image is provided, analyze it and use the visual information to better understand the user's requirements.222 223Always respond with code that can be executed or rendered directly.224 225Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text. Do NOT add the language name at the top of the code output."""226 227GENERIC_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert {language} developer. You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies for {language}.228 229Write clean, idiomatic, and runnable {language} code for the user's request. If possible, include comments and best practices. Output ONLY the code inside a ``` code block, and do not include any explanations or extra text. If the user provides a file or other context, use it as a reference. If the code is for a script or app, make it as self-contained as possible. Do NOT add the language name at the top of the code output."""230 231# Follow-up system prompt for modifying existing HTML files232FollowUpSystemPrompt = f"""You are an expert web developer modifying an existing HTML file.233The user wants to apply changes based on their request.234You MUST output ONLY the changes required using the following SEARCH/REPLACE block format. Do NOT output the entire file.235Explain the changes briefly *before* the blocks if necessary, but the code changes THEMSELVES MUST be within the blocks.236Format Rules:2371. Start with {SEARCH_START}2382. Provide the exact lines from the current code that need to be replaced.2393. Use {DIVIDER} to separate the search block from the replacement.2404. Provide the new lines that should replace the original lines.2415. End with {REPLACE_END}2426. You can use multiple SEARCH/REPLACE blocks if changes are needed in different parts of the file.2437. To insert code, use an empty SEARCH block (only {SEARCH_START} and {DIVIDER} on their lines) if inserting at the very beginning, otherwise provide the line *before* the insertion point in the SEARCH block and include that line plus the new lines in the REPLACE block.2448. To delete code, provide the lines to delete in the SEARCH block and leave the REPLACE block empty (only {DIVIDER} and {REPLACE_END} on their lines).2459. IMPORTANT: The SEARCH block must *exactly* match the current code, including indentation and whitespace.246Example Modifying Code:247```248Some explanation...249{SEARCH_START}250    <h1>Old Title</h1>251{DIVIDER}252    <h1>New Title</h1>253{REPLACE_END}254{SEARCH_START}255  </body>256{DIVIDER}257    <script>console.log("Added script");</script>258  </body>259{REPLACE_END}260```261Example Deleting Code:262```263Removing the paragraph...264{SEARCH_START}265  <p>This paragraph will be deleted.</p>266{DIVIDER}267{REPLACE_END}268```"""269 270# Follow-up system prompt for modifying existing transformers.js applications271TransformersJSFollowUpSystemPrompt = f"""You are an expert web developer modifying an existing transformers.js application.272The user wants to apply changes based on their request.273You MUST output ONLY the changes required using the following SEARCH/REPLACE block format. Do NOT output the entire file.274Explain the changes briefly *before* the blocks if necessary, but the code changes THEMSELVES MUST be within the blocks.275 276The transformers.js application consists of three files: index.html, index.js, and style.css.277When making changes, specify which file you're modifying by starting your search/replace blocks with the file name.278 279Format Rules:2801. Start with {SEARCH_START}2812. Provide the exact lines from the current code that need to be replaced.2823. Use {DIVIDER} to separate the search block from the replacement.2834. Provide the new lines that should replace the original lines.2845. End with {REPLACE_END}2856. You can use multiple SEARCH/REPLACE blocks if changes are needed in different parts of the file.2867. To insert code, use an empty SEARCH block (only {SEARCH_START} and {DIVIDER} on their lines) if inserting at the very beginning, otherwise provide the line *before* the insertion point in the SEARCH block and include that line plus the new lines in the REPLACE block.2878. To delete code, provide the lines to delete in the SEARCH block and leave the REPLACE block empty (only {DIVIDER} and {REPLACE_END} on their lines).2889. IMPORTANT: The SEARCH block must *exactly* match the current code, including indentation and whitespace.289 290Example Modifying HTML:291```292Changing the title in index.html...293{SEARCH_START}294    <title>Old Title</title>295{DIVIDER}296    <title>New Title</title>297{REPLACE_END}298```299 300Example Modifying JavaScript:301```302Adding a new function to index.js...303{SEARCH_START}304// Existing code305{DIVIDER}306// Existing code307 308function newFunction() {{309    console.log("New function added");310}}311{REPLACE_END}312```313 314Example Modifying CSS:315```316Changing background color in style.css...317{SEARCH_START}318body {{319    background-color: white;320}}321{DIVIDER}322body {{323    background-color: #f0f0f0;324}}325{REPLACE_END}326```"""327 328# Available models329AVAILABLE_MODELS = [330    {331        "name": "Moonshot Kimi-K2",332        "id": "moonshotai/Kimi-K2-Instruct",333        "description": "Moonshot AI Kimi-K2-Instruct model for code generation and general tasks"334    },335    {336        "name": "DeepSeek V3",337        "id": "deepseek-ai/DeepSeek-V3-0324",338        "description": "DeepSeek V3 model for code generation"339    },340    {341        "name": "DeepSeek R1", 342        "id": "deepseek-ai/DeepSeek-R1-0528",343        "description": "DeepSeek R1 model for code generation"344    },345    {346        "name": "ERNIE-4.5-VL",347        "id": "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT",348        "description": "ERNIE-4.5-VL model for multimodal code generation with image support"349    },350    {351        "name": "MiniMax M1",352        "id": "MiniMaxAI/MiniMax-M1-80k",353        "description": "MiniMax M1 model for code generation and general tasks"354    },355    {356        "name": "Qwen3-235B-A22B",357        "id": "Qwen/Qwen3-235B-A22B",358        "description": "Qwen3-235B-A22B model for code generation and general tasks"359    },360    {361        "name": "SmolLM3-3B",362        "id": "HuggingFaceTB/SmolLM3-3B",363        "description": "SmolLM3-3B model for code generation and general tasks"364    },365    {366        "name": "GLM-4.1V-9B-Thinking",367        "id": "THUDM/GLM-4.1V-9B-Thinking",368        "description": "GLM-4.1V-9B-Thinking model for multimodal code generation with image support"369    },370    {371        "name": "Qwen3-235B-A22B-Instruct-2507",372        "id": "Qwen/Qwen3-235B-A22B-Instruct-2507",373        "description": "Qwen3-235B-A22B-Instruct-2507 model for code generation and general tasks"374    },375    {376        "name": "Qwen3-Coder-480B-A35B",377        "id": "Qwen/Qwen3-Coder-480B-A35B-Instruct",378        "description": "Qwen3-Coder-480B-A35B-Instruct model for advanced code generation and programming tasks"379    }380]381 382DEMO_LIST = [383    {384        "title": "Todo App",385        "description": "Create a simple todo application with add, delete, and mark as complete functionality"386    },387    {388        "title": "Calculator",389        "description": "Build a basic calculator with addition, subtraction, multiplication, and division"390    },391    {392        "title": "Chat Interface",393        "description": "Build a chat interface with message history and user input"394    },395    {396        "title": "E-commerce Product Card",397        "description": "Create a product card component for an e-commerce website"398    },399    {400        "title": "Login Form",401        "description": "Build a responsive login form with validation"402    },403    {404        "title": "Dashboard Layout",405        "description": "Create a dashboard layout with sidebar navigation and main content area"406    },407    {408        "title": "Data Table",409        "description": "Build a data table with sorting and filtering capabilities"410    },411    {412        "title": "Image Gallery",413        "description": "Create an image gallery with lightbox functionality and responsive grid layout"414    },415    {416        "title": "UI from Image",417        "description": "Upload an image of a UI design and I'll generate the HTML/CSS code for it"418    },419    {420        "title": "Extract Text from Image",421        "description": "Upload an image containing text and I'll extract and process the text content"422    },423    {424        "title": "Website Redesign",425        "description": "Enter a website URL to extract its content and redesign it with a modern, responsive layout"426    },427    {428        "title": "Modify HTML",429        "description": "After generating HTML, ask me to modify it with specific changes using search/replace format"430    },431    {432        "title": "Search/Replace Example",433        "description": "Generate HTML first, then ask: 'Change the title to My New Title' or 'Add a blue background to the body'"434    },435    {436        "title": "Transformers.js App",437        "description": "Create a transformers.js application with AI/ML functionality using the transformers.js library"438    },439    {440        "title": "Svelte App",441        "description": "Create a modern Svelte application with TypeScript, Vite, and responsive design"442    }443]444 445# HF Inference Client446HF_TOKEN = os.getenv('HF_TOKEN')447if not HF_TOKEN:448    raise RuntimeError("HF_TOKEN environment variable is not set. Please set it to your Hugging Face API token.")449 450def get_inference_client(model_id, provider="auto"):451    """Return an InferenceClient with provider based on model_id and user selection."""452    if model_id == "moonshotai/Kimi-K2-Instruct":453        provider = "groq"454    return InferenceClient(455        provider=provider,456        api_key=HF_TOKEN,457        bill_to="huggingface"458    )459 460# Type definitions461History = List[Tuple[str, str]]462Messages = List[Dict[str, str]]463 464# Tavily Search Client465TAVILY_API_KEY = os.getenv('TAVILY_API_KEY')466tavily_client = None467if TAVILY_API_KEY:468    try:469        tavily_client = TavilyClient(api_key=TAVILY_API_KEY)470    except Exception as e:471        print(f"Failed to initialize Tavily client: {e}")472        tavily_client = None473 474def history_to_messages(history: History, system: str) -> Messages:475    messages = [{'role': 'system', 'content': system}]476    for h in history:477        # Handle multimodal content in history478        user_content = h[0]479        if isinstance(user_content, list):480            # Extract text from multimodal content481            text_content = ""482            for item in user_content:483                if isinstance(item, dict) and item.get("type") == "text":484                    text_content += item.get("text", "")485            user_content = text_content if text_content else str(user_content)486        487        messages.append({'role': 'user', 'content': user_content})488        messages.append({'role': 'assistant', 'content': h[1]})489    return messages490 491def messages_to_history(messages: Messages) -> Tuple[str, History]:492    assert messages[0]['role'] == 'system'493    history = []494    for q, r in zip(messages[1::2], messages[2::2]):495        # Extract text content from multimodal messages for history496        user_content = q['content']497        if isinstance(user_content, list):498            text_content = ""499            for item in user_content:500                if isinstance(item, dict) and item.get("type") == "text":501                    text_content += item.get("text", "")502            user_content = text_content if text_content else str(user_content)503        504        history.append([user_content, r['content']])505    return history506 507def history_to_chatbot_messages(history: History) -> List[Dict[str, str]]:508    """Convert history tuples to chatbot message format"""509    messages = []510    for user_msg, assistant_msg in history:511        # Handle multimodal content512        if isinstance(user_msg, list):513            text_content = ""514            for item in user_msg:515                if isinstance(item, dict) and item.get("type") == "text":516                    text_content += item.get("text", "")517            user_msg = text_content if text_content else str(user_msg)518        519        messages.append({"role": "user", "content": user_msg})520        messages.append({"role": "assistant", "content": assistant_msg})521    return messages522 523def remove_code_block(text):524    # Try to match code blocks with language markers525    patterns = [526        r'```(?:html|HTML)\n([\s\S]+?)\n```',  # Match ```html or ```HTML527        r'```\n([\s\S]+?)\n```',               # Match code blocks without language markers528        r'```([\s\S]+?)```'                      # Match code blocks without line breaks529    ]530    for pattern in patterns:531        match = re.search(pattern, text, re.DOTALL)532        if match:533            extracted = match.group(1).strip()534            # Remove a leading language marker line (e.g., 'python') if present535            if extracted.split('\n', 1)[0].strip().lower() in ['python', 'html', 'css', 'javascript', 'json', 'c', 'cpp', 'markdown', 'latex', 'jinja2', 'typescript', 'yaml', 'dockerfile', 'shell', 'r', 'sql', 'sql-mssql', 'sql-mysql', 'sql-mariadb', 'sql-sqlite', 'sql-cassandra', 'sql-plSQL', 'sql-hive', 'sql-pgsql', 'sql-gql', 'sql-gpsql', 'sql-sparksql', 'sql-esper']:536                return extracted.split('\n', 1)[1] if '\n' in extracted else ''537            return extracted538    # If no code block is found, check if the entire text is HTML539    if text.strip().startswith('<!DOCTYPE html>') or text.strip().startswith('<html') or text.strip().startswith('<'):540        return text.strip()541    # Special handling for python: remove python marker542    if text.strip().startswith('```python'):543        return text.strip()[9:-3].strip()544    # Remove a leading language marker line if present (fallback)545    lines = text.strip().split('\n', 1)546    if lines[0].strip().lower() in ['python', 'html', 'css', 'javascript', 'json', 'c', 'cpp', 'markdown', 'latex', 'jinja2', 'typescript', 'yaml', 'dockerfile', 'shell', 'r', 'sql', 'sql-mssql', 'sql-mysql', 'sql-mariadb', 'sql-sqlite', 'sql-cassandra', 'sql-plSQL', 'sql-hive', 'sql-pgsql', 'sql-gql', 'sql-gpsql', 'sql-sparksql', 'sql-esper']:547        return lines[1] if len(lines) > 1 else ''548    return text.strip()549 550def parse_transformers_js_output(text):551    """Parse transformers.js output and extract the three files (index.html, index.js, style.css)"""552    files = {553        'index.html': '',554        'index.js': '',555        'style.css': ''556    }557    558    # Patterns to match the three code blocks559    html_pattern = r'```html\s*\n([\s\S]+?)\n```'560    js_pattern = r'```javascript\s*\n([\s\S]+?)\n```'561    css_pattern = r'```css\s*\n([\s\S]+?)\n```'562    563    # Extract HTML content564    html_match = re.search(html_pattern, text, re.IGNORECASE)565    if html_match:566        files['index.html'] = html_match.group(1).strip()567    568    # Extract JavaScript content569    js_match = re.search(js_pattern, text, re.IGNORECASE)570    if js_match:571        files['index.js'] = js_match.group(1).strip()572    573    # Extract CSS content574    css_match = re.search(css_pattern, text, re.IGNORECASE)575    if css_match:576        files['style.css'] = css_match.group(1).strip()577    578    # Fallback: support === index.html === format if any file is missing579    if not (files['index.html'] and files['index.js'] and files['style.css']):580        # Use regex to extract sections581        html_fallback = re.search(r'===\s*index\.html\s*===\n([\s\S]+?)(?=\n===|$)', text, re.IGNORECASE)582        js_fallback = re.search(r'===\s*index\.js\s*===\n([\s\S]+?)(?=\n===|$)', text, re.IGNORECASE)583        css_fallback = re.search(r'===\s*style\.css\s*===\n([\s\S]+?)(?=\n===|$)', text, re.IGNORECASE)584        if html_fallback:585            files['index.html'] = html_fallback.group(1).strip()586        if js_fallback:587            files['index.js'] = js_fallback.group(1).strip()588        if css_fallback:589            files['style.css'] = css_fallback.group(1).strip()590    591    return files592 593def format_transformers_js_output(files):594    """Format the three files into a single display string"""595    output = []596    output.append("=== index.html ===")597    output.append(files['index.html'])598    output.append("\n=== index.js ===")599    output.append(files['index.js'])600    output.append("\n=== style.css ===")601    output.append(files['style.css'])602    return '\n'.join(output)603 604def parse_svelte_output(text):605    """Parse Svelte output to extract individual files"""606    files = {607        'src/App.svelte': '',608        'src/app.css': '',609        'src/lib/Counter.svelte': ''610    }611    612    # Split by code blocks613    import re614    code_blocks = re.findall(r'```(?:svelte|css)\n(.*?)```', text, re.DOTALL)615    616    # Handle partial generation - assign what we have617    if len(code_blocks) >= 1:618        files['src/App.svelte'] = code_blocks[0].strip()619    if len(code_blocks) >= 2:620        files['src/app.css'] = code_blocks[1].strip()621    if len(code_blocks) >= 3:622        files['src/lib/Counter.svelte'] = code_blocks[2].strip()623    624    return files625 626def format_svelte_output(files):627    """Format Svelte files into a single display string"""628    output = []629    output.append("=== src/App.svelte ===")630    output.append(files['src/App.svelte'])631    output.append("\n=== src/app.css ===")632    output.append(files['src/app.css'])633    output.append("\n=== src/lib/Counter.svelte ===")634    output.append(files['src/lib/Counter.svelte'])635    return '\n'.join(output)636 637def history_render(history: History):638    return gr.update(visible=True), history639 640def clear_history():641    return [], [], None, ""  # Empty lists for both tuple format and chatbot messages, None for file, empty string for website URL642 643def update_image_input_visibility(model):644    """Update image input visibility based on selected model"""645    is_ernie_vl = model.get("id") == "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT"646    is_glm_vl = model.get("id") == "THUDM/GLM-4.1V-9B-Thinking"647    return gr.update(visible=is_ernie_vl or is_glm_vl)648 649def process_image_for_model(image):650    """Convert image to base64 for model input"""651    if image is None:652        return None653    654    # Convert numpy array to PIL Image if needed655    import io656    import base64657    import numpy as np658    from PIL import Image659    660    # Handle numpy array from Gradio661    if isinstance(image, np.ndarray):662        image = Image.fromarray(image)663    664    buffer = io.BytesIO()665    image.save(buffer, format='PNG')666    img_str = base64.b64encode(buffer.getvalue()).decode()667    return f"data:image/png;base64,{img_str}"668 669def create_multimodal_message(text, image=None):670    """Create a multimodal message with text and optional image"""671    if image is None:672        return {"role": "user", "content": text}673    674    content = [675        {676            "type": "text",677            "text": text678        },679        {680            "type": "image_url",681            "image_url": {682                "url": process_image_for_model(image)683            }684        }685    ]686    687    return {"role": "user", "content": content}688 689def apply_search_replace_changes(original_content: str, changes_text: str) -> str:690    """Apply search/replace changes to content (HTML, Python, etc.)"""691    if not changes_text.strip():692        return original_content693    694    # Split the changes text into individual search/replace blocks695    blocks = []696    current_block = ""697    lines = changes_text.split('\n')698    699    for line in lines:700        if line.strip() == SEARCH_START:701            if current_block.strip():702                blocks.append(current_block.strip())703            current_block = line + '\n'704        elif line.strip() == REPLACE_END:705            current_block += line + '\n'706            blocks.append(current_block.strip())707            current_block = ""708        else:709            current_block += line + '\n'710    711    if current_block.strip():712        blocks.append(current_block.strip())713    714    modified_content = original_content715    716    for block in blocks:717        if not block.strip():718            continue719            720        # Parse the search/replace block721        lines = block.split('\n')722        search_lines = []723        replace_lines = []724        in_search = False725        in_replace = False726        727        for line in lines:728            if line.strip() == SEARCH_START:729                in_search = True730                in_replace = False731            elif line.strip() == DIVIDER:732                in_search = False733                in_replace = True734            elif line.strip() == REPLACE_END:735                in_replace = False736            elif in_search:737                search_lines.append(line)738            elif in_replace:739                replace_lines.append(line)740        741        # Apply the search/replace742        if search_lines:743            search_text = '\n'.join(search_lines).strip()744            replace_text = '\n'.join(replace_lines).strip()745            746            if search_text in modified_content:747                modified_content = modified_content.replace(search_text, replace_text)748            else:749                print(f"Warning: Search text not found in content: {search_text[:100]}...")750    751    return modified_content752 753def apply_transformers_js_search_replace_changes(original_formatted_content: str, changes_text: str) -> str:754    """Apply search/replace changes to transformers.js formatted content (three files)"""755    if not changes_text.strip():756        return original_formatted_content757    758    # Parse the original formatted content to get the three files759    files = parse_transformers_js_output(original_formatted_content)760    761    # Split the changes text into individual search/replace blocks762    blocks = []763    current_block = ""764    lines = changes_text.split('\n')765    766    for line in lines:767        if line.strip() == SEARCH_START:768            if current_block.strip():769                blocks.append(current_block.strip())770            current_block = line + '\n'771        elif line.strip() == REPLACE_END:772            current_block += line + '\n'773            blocks.append(current_block.strip())774            current_block = ""775        else:776            current_block += line + '\n'777    778    if current_block.strip():779        blocks.append(current_block.strip())780    781    # Process each block and apply changes to the appropriate file782    for block in blocks:783        if not block.strip():784            continue785            786        # Parse the search/replace block787        lines = block.split('\n')788        search_lines = []789        replace_lines = []790        in_search = False791        in_replace = False792        target_file = None793        794        for line in lines:795            if line.strip() == SEARCH_START:796                in_search = True797                in_replace = False798            elif line.strip() == DIVIDER:799                in_search = False800                in_replace = True801            elif line.strip() == REPLACE_END:802                in_replace = False803            elif in_search:804                search_lines.append(line)805            elif in_replace:806                replace_lines.append(line)807        808        # Determine which file this change targets based on the search content809        if search_lines:810            search_text = '\n'.join(search_lines).strip()811            replace_text = '\n'.join(replace_lines).strip()812            813            # Check which file contains the search text814            if search_text in files['index.html']:815                target_file = 'index.html'816            elif search_text in files['index.js']:817                target_file = 'index.js'818            elif search_text in files['style.css']:819                target_file = 'style.css'820            821            # Apply the change to the target file822            if target_file and search_text in files[target_file]:823                files[target_file] = files[target_file].replace(search_text, replace_text)824            else:825                print(f"Warning: Search text not found in any transformers.js file: {search_text[:100]}...")826    827    # Reformat the modified files828    return format_transformers_js_output(files)829 830# Updated for faster Tavily search and closer prompt usage831# Uses 'advanced' search_depth and auto_parameters=True for speed and relevance832 833def perform_web_search(query: str, max_results: int = 5, include_domains=None, exclude_domains=None) -> str:834    """Perform web search using Tavily with default parameters"""835    if not tavily_client:836        return "Web search is not available. Please set the TAVILY_API_KEY environment variable."837    838    try:839        # Use Tavily defaults with advanced search depth for better results840        search_params = {841            "search_depth": "advanced",842            "max_results": min(max(1, max_results), 20)843        }844        if include_domains is not None:845            search_params["include_domains"] = include_domains846        if exclude_domains is not None:847            search_params["exclude_domains"] = exclude_domains848 849        response = tavily_client.search(query, **search_params)850        851        search_results = []852        for result in response.get('results', []):853            title = result.get('title', 'No title')854            url = result.get('url', 'No URL')855            content = result.get('content', 'No content')856            search_results.append(f"Title: {title}\nURL: {url}\nContent: {content}\n")857        858        if search_results:859            return "Web Search Results:\n\n" + "\n---\n".join(search_results)860        else:861            return "No search results found."862            863    except Exception as e:864        return f"Search error: {str(e)}"865 866def enhance_query_with_search(query: str, enable_search: bool) -> str:867    """Enhance the query with web search results if search is enabled"""868    if not enable_search or not tavily_client:869        return query870    871    # Perform search to get relevant information872    search_results = perform_web_search(query)873    874    # Combine original query with search results875    enhanced_query = f"""Original Query: {query}876 877{search_results}878 879Please use the search results above to help create the requested application with the most up-to-date information and best practices."""880    881    return enhanced_query882 883def send_to_sandbox(code):884    # Add a wrapper to inject necessary permissions and ensure full HTML885    wrapped_code = f"""886    <!DOCTYPE html>887    <html>888    <head>889        <meta charset=\"UTF-8\">890        <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">891        <script>892            // Safe localStorage polyfill893            const safeStorage = {{894                _data: {{}},895                getItem: function(key) {{ return this._data[key] || null; }},896                setItem: function(key, value) {{ this._data[key] = value; }},897                removeItem: function(key) {{ delete this._data[key]; }},898                clear: function() {{ this._data = {{}}; }}899            }};900            Object.defineProperty(window, 'localStorage', {{901                value: safeStorage,902                writable: false903            }});904            window.onerror = function(message, source, lineno, colno, error) {{905                console.error('Error:', message);906            }};907        </script>908    </head>909    <body>910        {code}911    </body>912    </html>913    """914    encoded_html = base64.b64encode(wrapped_code.encode('utf-8')).decode('utf-8')915    data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"916    iframe = f'<iframe src="{data_uri}" width="100%" height="920px" sandbox="allow-scripts allow-same-origin allow-forms allow-popups allow-modals allow-presentation" allow="display-capture"></iframe>'917    return iframe918 919def demo_card_click(e: gr.EventData):920    try:921        # Get the index from the event data922        if hasattr(e, '_data') and e._data:923            # Try different ways to get the index924            if 'index' in e._data:925                index = e._data['index']926            elif 'component' in e._data and 'index' in e._data['component']:927                index = e._data['component']['index']928            elif 'target' in e._data and 'index' in e._data['target']:929                index = e._data['target']['index']930            else:931                # If we can't get the index, try to extract it from the card data932                index = 0933        else:934            index = 0935        936        # Ensure index is within bounds937        if index >= len(DEMO_LIST):938            index = 0939            940        return DEMO_LIST[index]['description']941    except (KeyError, IndexError, AttributeError) as e:942        # Return the first demo description as fallback943        return DEMO_LIST[0]['description']944 945def extract_text_from_image(image_path):946    """Extract text from image using OCR"""947    try:948        # Check if tesseract is available949        try:950            pytesseract.get_tesseract_version()951        except Exception:952            return "Error: Tesseract OCR is not installed. Please install Tesseract to extract text from images. See install_tesseract.md for instructions."953        954        # Read image using OpenCV955        image = cv2.imread(image_path)956        if image is None:957            return "Error: Could not read image file"958        959        # Convert to RGB (OpenCV uses BGR)960        image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)961        962        # Preprocess image for better OCR results963        # Convert to grayscale964        gray = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2GRAY)965        966        # Apply thresholding to get binary image967        _, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)968        969        # Extract text using pytesseract970        text = pytesseract.image_to_string(binary, config='--psm 6')971        972        return text.strip() if text.strip() else "No text found in image"973        974    except Exception as e:975        return f"Error extracting text from image: {e}"976 977def extract_text_from_file(file_path):978    if not file_path:979        return ""980    mime, _ = mimetypes.guess_type(file_path)981    ext = os.path.splitext(file_path)[1].lower()982    try:983        if ext == ".pdf":984            with open(file_path, "rb") as f:985                reader = PyPDF2.PdfReader(f)986                return "\n".join(page.extract_text() or "" for page in reader.pages)987        elif ext in [".txt", ".md"]:988            with open(file_path, "r", encoding="utf-8") as f:989                return f.read()990        elif ext == ".csv":991            with open(file_path, "r", encoding="utf-8") as f:992                return f.read()993        elif ext == ".docx":994            doc = docx.Document(file_path)995            return "\n".join([para.text for para in doc.paragraphs])996        elif ext.lower() in [".jpg", ".jpeg", ".png", ".bmp", ".tiff", ".tif", ".gif", ".webp"]:997            return extract_text_from_image(file_path)998        else:999            return ""1000    except Exception as e:1001        return f"Error extracting text: {e}"1002 1003def extract_website_content(url: str) -> str:1004    """Extract HTML code and content from a website URL"""1005    try:1006        # Validate URL1007        parsed_url = urlparse(url)1008        if not parsed_url.scheme:1009            url = "https://" + url1010            parsed_url = urlparse(url)1011        1012        if not parsed_url.netloc:1013            return "Error: Invalid URL provided"1014        1015        # Set comprehensive headers to mimic a real browser request1016        headers = {1017            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',1018            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',1019            'Accept-Language': 'en-US,en;q=0.9',1020            'Accept-Encoding': 'gzip, deflate, br',1021            'DNT': '1',1022            'Connection': 'keep-alive',1023            'Upgrade-Insecure-Requests': '1',1024            'Sec-Fetch-Dest': 'document',1025            'Sec-Fetch-Mode': 'navigate',1026            'Sec-Fetch-Site': 'none',1027            'Sec-Fetch-User': '?1',1028            'Cache-Control': 'max-age=0'1029        }1030        1031        # Create a session to maintain cookies and handle redirects1032        session = requests.Session()1033        session.headers.update(headers)1034        1035        # Make the request with retry logic1036        max_retries = 31037        for attempt in range(max_retries):1038            try:1039                response = session.get(url, timeout=15, allow_redirects=True)1040                response.raise_for_status()1041                break1042            except requests.exceptions.HTTPError as e:1043                if e.response.status_code == 403 and attempt < max_retries - 1:1044                    # Try with different User-Agent on 4031045                    session.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'1046                    continue1047                else:1048                    raise1049        1050        # Get the raw HTML content with proper encoding1051        try:1052            # Try to get the content with automatic encoding detection1053            response.encoding = response.apparent_encoding1054            raw_html = response.text1055        except:1056            # Fallback to UTF-8 if encoding detection fails1057            raw_html = response.content.decode('utf-8', errors='ignore')1058        1059        # Debug: Check if we got valid HTML1060        if not raw_html.strip().startswith('<!DOCTYPE') and not raw_html.strip().startswith('<html'):1061            print(f"Warning: Response doesn't look like HTML. First 200 chars: {raw_html[:200]}")1062            print(f"Response headers: {dict(response.headers)}")1063            print(f"Response encoding: {response.encoding}")1064            print(f"Apparent encoding: {response.apparent_encoding}")1065            1066            # Try alternative approaches1067            try:1068                raw_html = response.content.decode('latin-1', errors='ignore')1069                print("Tried latin-1 decoding")1070            except:1071                try:1072                    raw_html = response.content.decode('utf-8', errors='ignore')1073                    print("Tried UTF-8 decoding")1074                except:1075                    raw_html = response.content.decode('cp1252', errors='ignore')1076                    print("Tried cp1252 decoding")1077        1078        # Parse HTML content for analysis1079        soup = BeautifulSoup(raw_html, 'html.parser')1080        1081        # Check if this is a JavaScript-heavy site1082        script_tags = soup.find_all('script')1083        if len(script_tags) > 10:1084            print(f"Warning: This site has {len(script_tags)} script tags - it may be a JavaScript-heavy site")1085            print("The content might be loaded dynamically and not available in the initial HTML")1086        1087        # Extract title1088        title = soup.find('title')1089        title_text = title.get_text().strip() if title else "No title found"1090        1091        # Extract meta description1092        meta_desc = soup.find('meta', attrs={'name': 'description'})1093        description = meta_desc.get('content', '') if meta_desc else ""1094        1095        # Extract main content areas for analysis1096        content_sections = []1097        main_selectors = [1098            'main', 'article', '.content', '.main-content', '.post-content',1099            '#content', '#main', '.entry-content', '.post-body'1100        ]1101        1102        for selector in main_selectors:1103            elements = soup.select(selector)1104            for element in elements:1105                text = element.get_text().strip()1106                if len(text) > 100:  # Only include substantial content1107                    content_sections.append(text)1108        1109        # Extract navigation links for analysis1110        nav_links = []1111        nav_elements = soup.find_all(['nav', 'header'])1112        for nav in nav_elements:1113            links = nav.find_all('a')1114            for link in links:1115                link_text = link.get_text().strip()1116                link_href = link.get('href', '')1117                if link_text and link_href:1118                    nav_links.append(f"{link_text}: {link_href}")1119        1120        # Extract and fix image URLs in the HTML1121        img_elements = soup.find_all('img')1122        for img in img_elements:1123            src = img.get('src', '')1124            if src:1125                # Handle different URL formats1126                if src.startswith('//'):1127                    # Protocol-relative URL1128                    absolute_src = 'https:' + src1129                    img['src'] = absolute_src1130                elif src.startswith('/'):1131                    # Root-relative URL1132                    absolute_src = urljoin(url, src)1133                    img['src'] = absolute_src1134                elif not src.startswith(('http://', 'https://')):1135                    # Relative URL1136                    absolute_src = urljoin(url, src)1137                    img['src'] = absolute_src1138                # If it's already absolute, keep it as is1139                1140                # Also check for data-src (lazy loading) and other common attributes1141                data_src = img.get('data-src', '')1142                if data_src and not src:1143                    # Use data-src if src is empty1144                    if data_src.startswith('//'):1145                        absolute_data_src = 'https:' + data_src1146                        img['src'] = absolute_data_src1147                    elif data_src.startswith('/'):1148                        absolute_data_src = urljoin(url, data_src)1149                        img['src'] = absolute_data_src1150                    elif not data_src.startswith(('http://', 'https://')):1151                        absolute_data_src = urljoin(url, data_src)1152                        img['src'] = absolute_data_src1153                    else:1154                        img['src'] = data_src1155        1156        # Also fix background image URLs in style attributes1157        elements_with_style = soup.find_all(attrs={'style': True})1158        for element in elements_with_style:1159            style_attr = element.get('style', '')1160            # Find and replace relative URLs in background-image1161            import re1162            bg_pattern = r'background-image:\s*url\(["\']?([^"\']+)["\']?\)'1163            matches = re.findall(bg_pattern, style_attr, re.IGNORECASE)1164            for match in matches:1165                if match:1166                    if match.startswith('//'):1167                        absolute_bg = 'https:' + match1168                        style_attr = style_attr.replace(match, absolute_bg)1169                    elif match.startswith('/'):1170                        absolute_bg = urljoin(url, match)1171                        style_attr = style_attr.replace(match, absolute_bg)1172                    elif not match.startswith(('http://', 'https://')):1173                        absolute_bg = urljoin(url, match)1174                        style_attr = style_attr.replace(match, absolute_bg)1175            element['style'] = style_attr1176        1177        # Fix background images in <style> tags1178        style_elements = soup.find_all('style')1179        for style in style_elements:1180            if style.string:1181                style_content = style.string1182                # Find and replace relative URLs in background-image1183                bg_pattern = r'background-image:\s*url\(["\']?([^"\']+)["\']?\)'1184                matches = re.findall(bg_pattern, style_content, re.IGNORECASE)1185                for match in matches:1186                    if match:1187                        if match.startswith('//'):1188                            absolute_bg = 'https:' + match1189                            style_content = style_content.replace(match, absolute_bg)1190                        elif match.startswith('/'):1191                            absolute_bg = urljoin(url, match)1192                            style_content = style_content.replace(match, absolute_bg)1193                        elif not match.startswith(('http://', 'https://')):1194                            absolute_bg = urljoin(url, match)1195                            style_content = style_content.replace(match, absolute_bg)1196                style.string = style_content1197        1198        # Extract images for analysis (after fixing URLs)1199        images = []1200        img_elements = soup.find_all('img')

Showing the first 1,200 of 2399 lines. Download the file for the rest.