Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
import gradio as gr | |
import requests | |
import os | |
import re | |
SYSTEM_PROMPT = """You are an expert UI/UX designer specializing in redesigning HTML components with TailwindCSS. Transform the input HTML into a cleaner, more modern version with focus on spacing and layout precision. | |
Core Design Philosophy: | |
- SPACING FIRST: Prioritize proper spacing over complex styling | |
- PRESERVE EXISTING: Maintain the original color scheme and fonts when they exist | |
- SIMPLE & CLEAN: Focus on clean, minimal designs rather than overly decorative ones | |
- FLEXIBLE LAYOUTS: Use flexbox with proper flex properties for better control | |
Spacing & Layout Rules: | |
- Use consistent spacing scales: p-4, p-6, p-8 for padding; m-4, m-6, m-8 for margins | |
- Apply gap-4, gap-6, or gap-8 for flex/grid container spacing | |
- Use space-y-4, space-y-6 for vertical stacking | |
- Add flex-none to elements that should NOT stretch (buttons, labels, icons, fixed-width items) | |
- Use flex-1 or flex-auto only for elements that should grow/stretch | |
- Prefer specific widths (w-32, w-48, w-64) over arbitrary values | |
Color & Typography Preservation: | |
- ANALYZE the input HTML for existing color schemes (bg-*, text-*, border-*) | |
- REUSE those exact color classes in the redesigned version | |
- If input uses blue-500, continue using blue-* variants throughout | |
- If input has specific font classes (font-medium, text-lg), maintain that typography scale | |
- MANDATORY: ALWAYS add text-balance class to ALL titles and headings (h1, h2, h3, h4, h5, h6, and any element with large text like text-xl, text-2xl, etc.) for better text wrapping and visual balance | |
- Only introduce new colors if the original has none or uses basic colors | |
Dark Mode Support: | |
- DETECT dark mode classes in input (dark:*, bg-gray-900, text-white, etc.) | |
- If input HAS dark mode classes, PRESERVE and EXTEND them in the redesign | |
- If input has dark:bg-gray-800, continue using dark:* variants throughout | |
- If input has NO dark mode classes, DO NOT add any dark mode styling | |
- Maintain the same dark mode approach as the original (toggle-based or system-based) | |
Design Enhancement Guidelines: | |
- Improve visual hierarchy with better spacing, not more colors | |
- Add subtle shadows (shadow-sm, shadow-md) for depth | |
- Use rounded corners appropriately (rounded-lg, rounded-xl) | |
- Add hover states with opacity or subtle color shifts | |
- Implement focus states with ring utilities | |
- Use border utilities for clean separation | |
- Apply proper contrast ratios for accessibility | |
Layout Techniques: | |
- Use flex with gap instead of space-x/space-y when possible | |
- Apply justify-between, justify-center, items-center for alignment | |
- Use flex-none for buttons, icons, and fixed elements | |
- Apply max-w-* for content width constraints | |
- Use grid for complex layouts, flex for simple ones | |
Responsive Design Rules: | |
- ALWAYS ensure mobile-first responsive design | |
- Use responsive breakpoints: sm:, md:, lg:, xl: appropriately | |
- Stack elements vertically on mobile, arrange horizontally on larger screens | |
- Apply responsive padding: p-4 sm:p-6 lg:p-8 | |
- Use responsive text sizes: text-sm md:text-base lg:text-lg | |
- Implement responsive flexbox: flex-col md:flex-row | |
- Add responsive gaps: gap-4 md:gap-6 lg:gap-8 | |
- Ensure buttons and inputs are touch-friendly on mobile (min-h-10, p-3) | |
- Use responsive widths: w-full md:w-auto or w-full md:w-1/2 | |
- Apply responsive margins: mt-4 md:mt-0 for layout adjustments | |
Technical Requirements: | |
- Return ONLY the redesigned HTML code | |
- PRESERVE ALL FUNCTIONALITY: Keep every link (href), image (src), form action, onclick, etc. | |
- MAINTAIN ALL ATTRIBUTES: Preserve all IDs, classes, data-*, aria-*, name, value, placeholder, etc. | |
- KEEP ALL CONTENT: Preserve all text content, alt texts, button labels exactly as provided | |
- DO NOT REMOVE: Never remove links, images, inputs, buttons, or any functional elements | |
- DO NOT CHANGE: Keep all URLs, image sources, form targets, and JavaScript references unchanged | |
- ENHANCE ONLY STYLING: Only modify TailwindCSS classes for visual improvements | |
- PRESERVE STRUCTURE: Maintain the same HTML element hierarchy and nesting | |
Critical Preservation Rules: | |
- If input has <a href="...">Link</a>, output must have identical href and link text | |
- If input has <img src="..." alt="...">, output must preserve exact src and alt | |
- If input has form inputs with name/value/placeholder, keep them exactly the same | |
- If input has buttons with onclick or type attributes, preserve them completely | |
- If input has any data attributes (data-*), maintain them unchanged | |
- All original text content must remain identical | |
- MANDATORY TEXT-BALANCE RULE: Every heading (h1-h6) and large text element (text-xl, text-2xl, text-3xl, etc.) MUST include the text-balance class | |
Framework-Specific Preservation (React/Vue/Svelte/Angular): | |
- REACT: Preserve all JSX syntax: {variable}, {function()}, className, onClick, onChange, etc. | |
- VUE: Preserve all Vue directives: v-if, v-for, v-model, @click, :class, {{interpolation}}, etc. | |
- SVELTE: Preserve all Svelte syntax: {#if}, {#each}, on:click, bind:value, {variable}, etc. | |
- ANGULAR: Preserve all Angular syntax: *ngIf, *ngFor, (click), [class], {{interpolation}}, etc. | |
- ALPINE.JS: Preserve all Alpine directives: x-data, x-show, x-if, @click, :class, etc. | |
- HTMX: Preserve all HTMX attributes: hx-get, hx-post, hx-target, hx-swap, etc. | |
- Keep all curly braces, template literals, and dynamic expressions unchanged | |
- Maintain all event handlers and binding syntax exactly as provided | |
Focus on creating clean, spacious, and well-proportioned designs that feel premium through proper spacing rather than complex styling, while ensuring zero functional changes.""" | |
def extract_html_from_response(response_text): | |
"""Extract HTML code from model response""" | |
# Try to find HTML within code blocks first | |
html_pattern = r"```(?:html)?\s*(.*?)```" | |
matches = re.findall(html_pattern, response_text, re.DOTALL | re.IGNORECASE) | |
if matches: | |
return matches[0].strip() | |
# If no code blocks but response contains HTML tags, return the whole response | |
if re.search(r"<[^>]+>", response_text): | |
return response_text.strip() | |
# If no HTML found, return error | |
raise ValueError("No HTML content found in the response") | |
def redesign_html(html_input: str, user_prompt: str = "") -> str: | |
""" | |
Redesign HTML+TailwindCSS code with improved spacing, responsive design, and modern aesthetics. | |
This tool takes existing HTML with TailwindCSS classes and transforms it into a cleaner, | |
more modern version with better spacing, responsive design, and improved user experience. | |
IMPORTANT: This tool should only be used when users explicitly request to "redesign" HTML code. | |
Users must say "redesign" or similar intent for this tool to be activated. | |
Args: | |
html_input (str): The HTML code with TailwindCSS classes to be redesigned. | |
Can include React/Vue/Svelte/Angular syntax which will be preserved. | |
user_prompt (str, optional): Custom instructions for the redesign process. | |
Examples: "make it more colorful", "add animations", | |
"make it minimal", "improve mobile layout". | |
If empty, uses default redesign approach. | |
Returns: | |
str: The redesigned HTML code with improved TailwindCSS styling, preserving all | |
functionality, links, images, and framework-specific syntax. | |
Features: | |
- Preserves all functionality (links, images, forms, JavaScript) | |
- Maintains framework syntax (React JSX, Vue directives, etc.) | |
- Improves spacing and responsive design | |
- Preserves existing color schemes and fonts | |
- Adds proper flex-none for non-stretching elements | |
- Ensures mobile-first responsive design | |
- Supports dark mode when present in input | |
- Accepts custom user instructions for targeted redesign approaches | |
""" | |
# Check if HF_TOKEN is set | |
hf_token = os.getenv("HF_TOKEN") | |
if not hf_token: | |
return "Error: HF_TOKEN environment variable not set. Please set your HuggingFace token." | |
# Prepare the API request | |
url = "https://router.huggingface.co/sambanova/v1/chat/completions" | |
headers = { | |
"Authorization": f"Bearer {hf_token}", | |
"Content-Type": "application/json", | |
} | |
# Build messages with system prompt and user prompt | |
user_content = html_input | |
if user_prompt.strip(): | |
user_content = f"User instructions: {user_prompt.strip()}\n\nHTML to redesign:\n{html_input}" | |
messages = [ | |
{"role": "system", "content": SYSTEM_PROMPT}, | |
{"role": "user", "content": user_content}, | |
] | |
data = { | |
"messages": messages, | |
"model": "DeepSeek-V3-0324", | |
"stream": False, | |
"temperature": 0.8, | |
} | |
try: | |
response = requests.post(url, headers=headers, json=data, timeout=30) | |
response.raise_for_status() | |
result = response.json() | |
response_content = result["choices"][0]["message"]["content"] | |
# Extract HTML from the response | |
try: | |
html_content = extract_html_from_response(response_content) | |
return html_content | |
except ValueError as e: | |
return f"Error: {str(e)}. Response was: {response_content[:200]}..." | |
except requests.exceptions.RequestException as e: | |
return f"Error: Failed to connect to API - {str(e)}" | |
except KeyError as e: | |
return f"Error: Unexpected API response format - {str(e)}" | |
except Exception as e: | |
return f"Error: {str(e)}" | |
# Custom CSS for better HTML code display | |
custom_css = """ | |
<style> | |
/* Better formatting for HTML code display */ | |
.message-wrap .prose { | |
max-width: none !important; | |
} | |
.message-wrap pre { | |
white-space: pre-wrap !important; | |
word-break: break-all !important; | |
background: #1e1e1e !important; | |
color: #d4d4d4 !important; | |
padding: 16px !important; | |
border-radius: 8px !important; | |
border: 1px solid #333 !important; | |
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace !important; | |
font-size: 14px !important; | |
line-height: 1.5 !important; | |
} | |
</style> | |
""" | |
# Create Gradio interface | |
demo = gr.Interface( | |
fn=redesign_html, | |
inputs=[ | |
gr.Textbox( | |
label="Custom Instructions (Optional)", | |
placeholder="Enter specific instructions for the redesign (e.g., 'make it more colorful', 'add animations', 'make it minimal')...", | |
lines=2, | |
value="", | |
), | |
gr.Textbox( | |
label="HTML Input", | |
placeholder="Paste your HTML+TailwindCSS code here...", | |
lines=10, | |
value='<div class="p-4 border"><h1 class="text-xl">Welcome</h1><p>This is a basic card</p><button class="bg-blue-500 text-white px-4 py-2">Click me</button></div>', | |
), | |
], | |
outputs=gr.Code(language="html", label="Redesigned HTML"), | |
title="Redesigner (MCP Server)", | |
description=""" | |
**MCP Server Tool for HTML Redesigning** | |
This is an MCP (Model Context Protocol) server that provides HTML redesign capabilities to LLMs. | |
**Powered by DeepSeek-V3-0324** - An advanced model specifically excellent at UI/UX design tasks. | |
**IMPORTANT FOR LLM USAGE:** This tool should only be activated when users explicitly request to "redesign" HTML code. | |
Users must use the word "redesign" or similar intent (e.g., "improve the design", "make it look better") for this tool to be used. | |
**Features:** | |
- Improves HTML+TailwindCSS with better spacing and responsive design | |
- Preserves all functionality (links, images, forms, JavaScript) | |
- Maintains framework syntax (React, Vue, Svelte, Angular) | |
- Supports dark mode when present in input | |
- Mobile-first responsive design implementation | |
- Custom user instructions for targeted redesign approaches | |
**Usage:** LLMs can use this tool when users ask to redesign HTML code by providing the HTML as input. | |
""", | |
examples=[ | |
[ | |
"Make it more modern and colorful", | |
'<div class="p-4 border"><h1 class="text-xl">Welcome</h1><p>This is a basic card</p><button class="bg-blue-500 text-white px-4 py-2">Click me</button></div>', | |
], | |
[ | |
"Add subtle animations and improve spacing", | |
'<form class="space-y-4"><input type="email" placeholder="Email" class="border p-2 w-full"><input type="password" placeholder="Password" class="border p-2 w-full"><button type="submit" class="bg-green-500 text-white p-2">Login</button></form>', | |
], | |
[ | |
"", | |
'<nav class="flex justify-between p-4 bg-gray-100"><div class="font-bold">Logo</div><ul class="flex space-x-4"><li><a href="#" class="text-blue-500">Home</a></li><li><a href="#" class="text-blue-500">About</a></li></ul></nav>', | |
], | |
], | |
css=custom_css, | |
) | |
if __name__ == "__main__": | |
demo.launch(mcp_server=True) | |