Spaces:
Running
Running
add svelte app support
Browse files
app.py
CHANGED
|
@@ -90,6 +90,81 @@ The style.css should contain all the styling for the application.
|
|
| 90 |
|
| 91 |
Always output only the three code blocks as shown above, and do not include any explanations or extra text."""
|
| 92 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
TRANSFORMERS_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.
|
| 94 |
|
| 95 |
You will generate THREE separate files: index.html, index.js, and style.css.
|
|
@@ -360,6 +435,10 @@ DEMO_LIST = [
|
|
| 360 |
{
|
| 361 |
"title": "Transformers.js App",
|
| 362 |
"description": "Create a transformers.js application with AI/ML functionality using the transformers.js library"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 363 |
}
|
| 364 |
]
|
| 365 |
|
|
@@ -522,6 +601,39 @@ def format_transformers_js_output(files):
|
|
| 522 |
output.append(files['style.css'])
|
| 523 |
return '\n'.join(output)
|
| 524 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 525 |
def history_render(history: History):
|
| 526 |
return gr.update(visible=True), history
|
| 527 |
|
|
@@ -1246,7 +1358,8 @@ def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optio
|
|
| 1246 |
'IMPORTED PROJECT FROM HUGGING FACE SPACE' in last_assistant_msg or
|
| 1247 |
'=== index.html ===' in last_assistant_msg or
|
| 1248 |
'=== index.js ===' in last_assistant_msg or
|
| 1249 |
-
'=== style.css ===' in last_assistant_msg
|
|
|
|
| 1250 |
has_existing_content = True
|
| 1251 |
|
| 1252 |
# Choose system prompt based on context
|
|
@@ -1254,6 +1367,8 @@ def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optio
|
|
| 1254 |
# Use follow-up prompt for modifying existing content
|
| 1255 |
if language == "transformers.js":
|
| 1256 |
system_prompt = TransformersJSFollowUpSystemPrompt
|
|
|
|
|
|
|
| 1257 |
else:
|
| 1258 |
system_prompt = FollowUpSystemPrompt
|
| 1259 |
else:
|
|
@@ -1262,6 +1377,8 @@ def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optio
|
|
| 1262 |
system_prompt = HTML_SYSTEM_PROMPT_WITH_SEARCH if enable_search else HTML_SYSTEM_PROMPT
|
| 1263 |
elif language == "transformers.js":
|
| 1264 |
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH if enable_search else TRANSFORMERS_JS_SYSTEM_PROMPT
|
|
|
|
|
|
|
| 1265 |
else:
|
| 1266 |
system_prompt = GENERIC_SYSTEM_PROMPT_WITH_SEARCH.format(language=language) if enable_search else GENERIC_SYSTEM_PROMPT.format(language=language)
|
| 1267 |
|
|
@@ -1351,6 +1468,14 @@ This will help me create a better design for you."""
|
|
| 1351 |
history_output: history_to_chatbot_messages(_history),
|
| 1352 |
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Generating transformers.js app...</div>",
|
| 1353 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1354 |
else:
|
| 1355 |
clean_code = remove_code_block(content)
|
| 1356 |
if has_existing_content:
|
|
@@ -1414,6 +1539,39 @@ This will help me create a better design for you."""
|
|
| 1414 |
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Error parsing transformers.js output. Please try again.</div>",
|
| 1415 |
history_output: history_to_chatbot_messages(_history),
|
| 1416 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1417 |
elif has_existing_content:
|
| 1418 |
# Handle modification of existing content
|
| 1419 |
final_code = remove_code_block(content)
|
|
@@ -1655,7 +1813,7 @@ with gr.Blocks(
|
|
| 1655 |
)
|
| 1656 |
# Language dropdown for code generation
|
| 1657 |
language_choices = [
|
| 1658 |
-
"html", "python", "c", "cpp", "markdown", "latex", "json", "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"
|
| 1659 |
]
|
| 1660 |
language_dropdown = gr.Dropdown(
|
| 1661 |
choices=language_choices,
|
|
@@ -1692,7 +1850,8 @@ with gr.Blocks(
|
|
| 1692 |
("Gradio (Python)", "gradio"),
|
| 1693 |
("Streamlit (Python)", "streamlit"),
|
| 1694 |
("Static (HTML)", "static"),
|
| 1695 |
-
("Transformers.js", "transformers.js")
|
|
|
|
| 1696 |
]
|
| 1697 |
sdk_dropdown = gr.Dropdown(
|
| 1698 |
choices=[x[0] for x in sdk_choices],
|
|
@@ -1804,6 +1963,8 @@ with gr.Blocks(
|
|
| 1804 |
def update_sdk_based_on_language(language):
|
| 1805 |
if language == "transformers.js":
|
| 1806 |
return gr.update(value="Transformers.js")
|
|
|
|
|
|
|
| 1807 |
elif language == "html":
|
| 1808 |
return gr.update(value="Static (HTML)")
|
| 1809 |
else:
|
|
@@ -1822,6 +1983,9 @@ with gr.Blocks(
|
|
| 1822 |
return send_to_sandbox(files['index.html'])
|
| 1823 |
else:
|
| 1824 |
return "<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>"
|
|
|
|
|
|
|
|
|
|
| 1825 |
else:
|
| 1826 |
return "<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>"
|
| 1827 |
|
|
@@ -1905,7 +2069,8 @@ with gr.Blocks(
|
|
| 1905 |
"Gradio (Python)": "gradio",
|
| 1906 |
"Streamlit (Python)": "docker", # Use 'docker' for Streamlit Spaces
|
| 1907 |
"Static (HTML)": "static",
|
| 1908 |
-
"Transformers.js": "static" # Transformers.js uses static SDK
|
|
|
|
| 1909 |
}
|
| 1910 |
sdk = sdk_map.get(sdk_name, "gradio")
|
| 1911 |
|
|
@@ -2060,6 +2225,106 @@ with gr.Blocks(
|
|
| 2060 |
|
| 2061 |
except Exception as e:
|
| 2062 |
return gr.update(value=f"Error duplicating Transformers.js space: {e}. If this is a RepoUrl object error, ensure you are not accessing a .url attribute and use str(duplicated_repo) for the URL.", visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2063 |
# Other SDKs (existing logic)
|
| 2064 |
if sdk == "static":
|
| 2065 |
import time
|
|
|
|
| 90 |
|
| 91 |
Always output only the three code blocks as shown above, and do not include any explanations or extra text."""
|
| 92 |
|
| 93 |
+
SVELTE_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 |
+
|
| 95 |
+
IMPORTANT: You MUST output ONLY the custom files in the following format:
|
| 96 |
+
|
| 97 |
+
```svelte
|
| 98 |
+
<!-- src/App.svelte content here -->
|
| 99 |
+
```
|
| 100 |
+
|
| 101 |
+
```css
|
| 102 |
+
/* src/app.css content here */
|
| 103 |
+
```
|
| 104 |
+
|
| 105 |
+
```svelte
|
| 106 |
+
<!-- src/lib/Counter.svelte content here -->
|
| 107 |
+
```
|
| 108 |
+
|
| 109 |
+
Requirements:
|
| 110 |
+
1. Create a modern, responsive Svelte application
|
| 111 |
+
2. Use TypeScript for better type safety
|
| 112 |
+
3. Create a clean, professional UI with good user experience
|
| 113 |
+
4. Make the application fully responsive for mobile devices
|
| 114 |
+
5. Use modern CSS practices and Svelte best practices
|
| 115 |
+
6. Include proper error handling and loading states
|
| 116 |
+
7. Follow accessibility best practices
|
| 117 |
+
8. Use Svelte's reactive features effectively
|
| 118 |
+
9. Include proper component structure and organization
|
| 119 |
+
|
| 120 |
+
The 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 |
+
|
| 125 |
+
The 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 |
+
|
| 127 |
+
Always output only the three code blocks as shown above, and do not include any explanations or extra text."""
|
| 128 |
+
|
| 129 |
+
SVELTE_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 |
+
|
| 131 |
+
You will generate ONLY the custom files that need user-specific content.
|
| 132 |
+
|
| 133 |
+
IMPORTANT: You MUST output ONLY the custom files in the following format:
|
| 134 |
+
|
| 135 |
+
```svelte
|
| 136 |
+
<!-- src/App.svelte content here -->
|
| 137 |
+
```
|
| 138 |
+
|
| 139 |
+
```css
|
| 140 |
+
/* src/app.css content here */
|
| 141 |
+
```
|
| 142 |
+
|
| 143 |
+
```svelte
|
| 144 |
+
<!-- src/lib/Counter.svelte content here -->
|
| 145 |
+
```
|
| 146 |
+
|
| 147 |
+
Requirements:
|
| 148 |
+
1. Create a modern, responsive Svelte application
|
| 149 |
+
2. Use TypeScript for better type safety
|
| 150 |
+
3. Create a clean, professional UI with good user experience
|
| 151 |
+
4. Make the application fully responsive for mobile devices
|
| 152 |
+
5. Use modern CSS practices and Svelte best practices
|
| 153 |
+
6. Include proper error handling and loading states
|
| 154 |
+
7. Follow accessibility best practices
|
| 155 |
+
8. Use Svelte's reactive features effectively
|
| 156 |
+
9. Include proper component structure and organization
|
| 157 |
+
10. Use web search to find the latest Svelte patterns, libraries, and best practices
|
| 158 |
+
|
| 159 |
+
The 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 |
+
|
| 164 |
+
The 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 |
+
|
| 166 |
+
Always output only the three code blocks as shown above, and do not include any explanations or extra text."""
|
| 167 |
+
|
| 168 |
TRANSFORMERS_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 |
|
| 170 |
You will generate THREE separate files: index.html, index.js, and style.css.
|
|
|
|
| 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 |
|
|
|
|
| 601 |
output.append(files['style.css'])
|
| 602 |
return '\n'.join(output)
|
| 603 |
|
| 604 |
+
def 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 blocks
|
| 613 |
+
import re
|
| 614 |
+
code_blocks = re.findall(r'```(?:svelte|css)\n(.*?)```', text, re.DOTALL)
|
| 615 |
+
|
| 616 |
+
# Handle partial generation - assign what we have
|
| 617 |
+
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 files
|
| 625 |
+
|
| 626 |
+
def 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 |
+
|
| 637 |
def history_render(history: History):
|
| 638 |
return gr.update(visible=True), history
|
| 639 |
|
|
|
|
| 1358 |
'IMPORTED PROJECT FROM HUGGING FACE SPACE' in last_assistant_msg or
|
| 1359 |
'=== index.html ===' in last_assistant_msg or
|
| 1360 |
'=== index.js ===' in last_assistant_msg or
|
| 1361 |
+
'=== style.css ===' in last_assistant_msg or
|
| 1362 |
+
'=== src/App.svelte ===' in last_assistant_msg):
|
| 1363 |
has_existing_content = True
|
| 1364 |
|
| 1365 |
# Choose system prompt based on context
|
|
|
|
| 1367 |
# Use follow-up prompt for modifying existing content
|
| 1368 |
if language == "transformers.js":
|
| 1369 |
system_prompt = TransformersJSFollowUpSystemPrompt
|
| 1370 |
+
elif language == "svelte":
|
| 1371 |
+
system_prompt = FollowUpSystemPrompt # Use generic follow-up for Svelte
|
| 1372 |
else:
|
| 1373 |
system_prompt = FollowUpSystemPrompt
|
| 1374 |
else:
|
|
|
|
| 1377 |
system_prompt = HTML_SYSTEM_PROMPT_WITH_SEARCH if enable_search else HTML_SYSTEM_PROMPT
|
| 1378 |
elif language == "transformers.js":
|
| 1379 |
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT_WITH_SEARCH if enable_search else TRANSFORMERS_JS_SYSTEM_PROMPT
|
| 1380 |
+
elif language == "svelte":
|
| 1381 |
+
system_prompt = SVELTE_SYSTEM_PROMPT_WITH_SEARCH if enable_search else SVELTE_SYSTEM_PROMPT
|
| 1382 |
else:
|
| 1383 |
system_prompt = GENERIC_SYSTEM_PROMPT_WITH_SEARCH.format(language=language) if enable_search else GENERIC_SYSTEM_PROMPT.format(language=language)
|
| 1384 |
|
|
|
|
| 1468 |
history_output: history_to_chatbot_messages(_history),
|
| 1469 |
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Generating transformers.js app...</div>",
|
| 1470 |
}
|
| 1471 |
+
elif language == "svelte":
|
| 1472 |
+
# For Svelte, just show the content as it streams
|
| 1473 |
+
# We'll parse it properly in the final response
|
| 1474 |
+
yield {
|
| 1475 |
+
code_output: gr.update(value=content, language="html"),
|
| 1476 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1477 |
+
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Generating Svelte app...</div>",
|
| 1478 |
+
}
|
| 1479 |
else:
|
| 1480 |
clean_code = remove_code_block(content)
|
| 1481 |
if has_existing_content:
|
|
|
|
| 1539 |
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Error parsing transformers.js output. Please try again.</div>",
|
| 1540 |
history_output: history_to_chatbot_messages(_history),
|
| 1541 |
}
|
| 1542 |
+
elif language == "svelte":
|
| 1543 |
+
# Handle Svelte output
|
| 1544 |
+
files = parse_svelte_output(content)
|
| 1545 |
+
if files['src/App.svelte'] and files['src/app.css']:
|
| 1546 |
+
# Model returned complete Svelte output
|
| 1547 |
+
formatted_output = format_svelte_output(files)
|
| 1548 |
+
_history.append([query, formatted_output])
|
| 1549 |
+
yield {
|
| 1550 |
+
code_output: formatted_output,
|
| 1551 |
+
history: _history,
|
| 1552 |
+
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your Svelte code using the download button above.</div>",
|
| 1553 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1554 |
+
}
|
| 1555 |
+
elif has_existing_content:
|
| 1556 |
+
# Model returned search/replace changes for Svelte - apply them
|
| 1557 |
+
last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
|
| 1558 |
+
modified_content = apply_search_replace_changes(last_content, content)
|
| 1559 |
+
_history.append([query, modified_content])
|
| 1560 |
+
yield {
|
| 1561 |
+
code_output: modified_content,
|
| 1562 |
+
history: _history,
|
| 1563 |
+
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your Svelte code using the download button above.</div>",
|
| 1564 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1565 |
+
}
|
| 1566 |
+
else:
|
| 1567 |
+
# Fallback if parsing failed - just use the raw content
|
| 1568 |
+
_history.append([query, content])
|
| 1569 |
+
yield {
|
| 1570 |
+
code_output: content,
|
| 1571 |
+
history: _history,
|
| 1572 |
+
sandbox: "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your Svelte code using the download button above.</div>",
|
| 1573 |
+
history_output: history_to_chatbot_messages(_history),
|
| 1574 |
+
}
|
| 1575 |
elif has_existing_content:
|
| 1576 |
# Handle modification of existing content
|
| 1577 |
final_code = remove_code_block(content)
|
|
|
|
| 1813 |
)
|
| 1814 |
# Language dropdown for code generation
|
| 1815 |
language_choices = [
|
| 1816 |
+
"html", "python", "transformers.js", "svelte", "c", "cpp", "markdown", "latex", "json", "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"
|
| 1817 |
]
|
| 1818 |
language_dropdown = gr.Dropdown(
|
| 1819 |
choices=language_choices,
|
|
|
|
| 1850 |
("Gradio (Python)", "gradio"),
|
| 1851 |
("Streamlit (Python)", "streamlit"),
|
| 1852 |
("Static (HTML)", "static"),
|
| 1853 |
+
("Transformers.js", "transformers.js"),
|
| 1854 |
+
("Svelte", "svelte")
|
| 1855 |
]
|
| 1856 |
sdk_dropdown = gr.Dropdown(
|
| 1857 |
choices=[x[0] for x in sdk_choices],
|
|
|
|
| 1963 |
def update_sdk_based_on_language(language):
|
| 1964 |
if language == "transformers.js":
|
| 1965 |
return gr.update(value="Transformers.js")
|
| 1966 |
+
elif language == "svelte":
|
| 1967 |
+
return gr.update(value="Svelte")
|
| 1968 |
elif language == "html":
|
| 1969 |
return gr.update(value="Static (HTML)")
|
| 1970 |
else:
|
|
|
|
| 1983 |
return send_to_sandbox(files['index.html'])
|
| 1984 |
else:
|
| 1985 |
return "<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>"
|
| 1986 |
+
elif language == "svelte":
|
| 1987 |
+
# For Svelte, we can't preview the compiled app, so show a message
|
| 1988 |
+
return "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML. Please download your Svelte code and deploy it to see the result.</div>"
|
| 1989 |
else:
|
| 1990 |
return "<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>"
|
| 1991 |
|
|
|
|
| 2069 |
"Gradio (Python)": "gradio",
|
| 2070 |
"Streamlit (Python)": "docker", # Use 'docker' for Streamlit Spaces
|
| 2071 |
"Static (HTML)": "static",
|
| 2072 |
+
"Transformers.js": "static", # Transformers.js uses static SDK
|
| 2073 |
+
"Svelte": "static" # Svelte uses static SDK
|
| 2074 |
}
|
| 2075 |
sdk = sdk_map.get(sdk_name, "gradio")
|
| 2076 |
|
|
|
|
| 2225 |
|
| 2226 |
except Exception as e:
|
| 2227 |
return gr.update(value=f"Error duplicating Transformers.js space: {e}. If this is a RepoUrl object error, ensure you are not accessing a .url attribute and use str(duplicated_repo) for the URL.", visible=True)
|
| 2228 |
+
# Svelte logic
|
| 2229 |
+
elif sdk_name == "Svelte" and not is_update:
|
| 2230 |
+
try:
|
| 2231 |
+
# Use duplicate_space to create a Svelte template space
|
| 2232 |
+
from huggingface_hub import duplicate_space
|
| 2233 |
+
|
| 2234 |
+
# Duplicate the Svelte template space
|
| 2235 |
+
duplicated_repo = duplicate_space(
|
| 2236 |
+
from_id="static-templates/svelte",
|
| 2237 |
+
to_id=space_name.strip(),
|
| 2238 |
+
token=token.token,
|
| 2239 |
+
exist_ok=True
|
| 2240 |
+
)
|
| 2241 |
+
print("Duplicated Svelte repo result:", duplicated_repo, type(duplicated_repo))
|
| 2242 |
+
# Show the duplicated space URL immediately for user feedback
|
| 2243 |
+
gr.update(value=f"β
Space duplicated! [Open your new Svelte Space here]({str(duplicated_repo)})", visible=True)
|
| 2244 |
+
# Parse the Svelte output to get the custom files
|
| 2245 |
+
files = parse_svelte_output(code)
|
| 2246 |
+
|
| 2247 |
+
if not files['src/App.svelte']:
|
| 2248 |
+
return gr.update(value="Error: Could not parse Svelte output. Please regenerate the code.", visible=True)
|
| 2249 |
+
|
| 2250 |
+
# Upload only the custom Svelte files to the duplicated space
|
| 2251 |
+
import tempfile
|
| 2252 |
+
|
| 2253 |
+
# Upload src/App.svelte (required)
|
| 2254 |
+
with tempfile.NamedTemporaryFile("w", suffix=".svelte", delete=False) as f:
|
| 2255 |
+
f.write(files['src/App.svelte'])
|
| 2256 |
+
temp_path = f.name
|
| 2257 |
+
|
| 2258 |
+
try:
|
| 2259 |
+
api.upload_file(
|
| 2260 |
+
path_or_fileobj=temp_path,
|
| 2261 |
+
path_in_repo="src/App.svelte",
|
| 2262 |
+
repo_id=repo_id,
|
| 2263 |
+
repo_type="space"
|
| 2264 |
+
)
|
| 2265 |
+
except Exception as e:
|
| 2266 |
+
error_msg = str(e)
|
| 2267 |
+
if "403 Forbidden" in error_msg and "write token" in error_msg:
|
| 2268 |
+
return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True)
|
| 2269 |
+
else:
|
| 2270 |
+
return gr.update(value=f"Error uploading src/App.svelte: {e}", visible=True)
|
| 2271 |
+
finally:
|
| 2272 |
+
import os
|
| 2273 |
+
os.unlink(temp_path)
|
| 2274 |
+
|
| 2275 |
+
# Upload src/app.css (optional)
|
| 2276 |
+
if files['src/app.css']:
|
| 2277 |
+
with tempfile.NamedTemporaryFile("w", suffix=".css", delete=False) as f:
|
| 2278 |
+
f.write(files['src/app.css'])
|
| 2279 |
+
temp_path = f.name
|
| 2280 |
+
|
| 2281 |
+
try:
|
| 2282 |
+
api.upload_file(
|
| 2283 |
+
path_or_fileobj=temp_path,
|
| 2284 |
+
path_in_repo="src/app.css",
|
| 2285 |
+
repo_id=repo_id,
|
| 2286 |
+
repo_type="space"
|
| 2287 |
+
)
|
| 2288 |
+
except Exception as e:
|
| 2289 |
+
error_msg = str(e)
|
| 2290 |
+
if "403 Forbidden" in error_msg and "write token" in error_msg:
|
| 2291 |
+
return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True)
|
| 2292 |
+
else:
|
| 2293 |
+
return gr.update(value=f"Error uploading src/app.css: {e}", visible=True)
|
| 2294 |
+
finally:
|
| 2295 |
+
import os
|
| 2296 |
+
os.unlink(temp_path)
|
| 2297 |
+
|
| 2298 |
+
# Upload src/lib/Counter.svelte (optional)
|
| 2299 |
+
if files['src/lib/Counter.svelte']:
|
| 2300 |
+
with tempfile.NamedTemporaryFile("w", suffix=".svelte", delete=False) as f:
|
| 2301 |
+
f.write(files['src/lib/Counter.svelte'])
|
| 2302 |
+
temp_path = f.name
|
| 2303 |
+
|
| 2304 |
+
try:
|
| 2305 |
+
api.upload_file(
|
| 2306 |
+
path_or_fileobj=temp_path,
|
| 2307 |
+
path_in_repo="src/lib/Counter.svelte",
|
| 2308 |
+
repo_id=repo_id,
|
| 2309 |
+
repo_type="space"
|
| 2310 |
+
)
|
| 2311 |
+
except Exception as e:
|
| 2312 |
+
error_msg = str(e)
|
| 2313 |
+
if "403 Forbidden" in error_msg and "write token" in error_msg:
|
| 2314 |
+
return gr.update(value=f"Error: Permission denied. Please ensure you have write access to {repo_id} and your token has the correct permissions.", visible=True)
|
| 2315 |
+
else:
|
| 2316 |
+
return gr.update(value=f"Error uploading src/lib/Counter.svelte: {e}", visible=True)
|
| 2317 |
+
finally:
|
| 2318 |
+
import os
|
| 2319 |
+
os.unlink(temp_path)
|
| 2320 |
+
|
| 2321 |
+
# Success - all files uploaded
|
| 2322 |
+
space_url = f"https://huggingface.co/spaces/{repo_id}"
|
| 2323 |
+
action_text = "Updated" if is_update else "Deployed"
|
| 2324 |
+
return gr.update(value=f"β
{action_text}! [Open your Svelte Space here]({space_url})", visible=True)
|
| 2325 |
+
|
| 2326 |
+
except Exception as e:
|
| 2327 |
+
return gr.update(value=f"Error duplicating Svelte space: {e}. If this is a RepoUrl object error, ensure you are not accessing a .url attribute and use str(duplicated_repo) for the URL.", visible=True)
|
| 2328 |
# Other SDKs (existing logic)
|
| 2329 |
if sdk == "static":
|
| 2330 |
import time
|