Spaces:
Running
Running
remove svelte and tavily comments
Browse files
app.py
CHANGED
|
@@ -1512,7 +1512,7 @@ GLM45V_HTML_SYSTEM_PROMPT = """You are an expert front-end developer.
|
|
| 1512 |
Output a COMPLETE, STANDALONE HTML document that renders directly in a browser.
|
| 1513 |
|
| 1514 |
Hard constraints:
|
| 1515 |
-
- DO NOT use React, ReactDOM, JSX, Babel, Vue, Angular,
|
| 1516 |
- Use ONLY plain HTML, CSS, and vanilla JavaScript.
|
| 1517 |
- Allowed external resources: Tailwind CSS CDN, Font Awesome CDN, Google Fonts.
|
| 1518 |
- Do NOT escape characters (no \\n, \\t, or escaped quotes). Output raw HTML/JS/CSS.
|
|
@@ -1662,61 +1662,6 @@ Requirements:
|
|
| 1662 |
IMPORTANT: Always include "Built with anycoder" as clickable text in the header/top section of your application that links to https://huggingface.co/spaces/akhaliq/anycoder
|
| 1663 |
"""
|
| 1664 |
|
| 1665 |
-
SVELTE_SYSTEM_PROMPT = """You are an expert Svelte developer creating a modern Svelte application.
|
| 1666 |
-
|
| 1667 |
-
**🚨 CRITICAL: DO NOT Generate README.md Files**
|
| 1668 |
-
- NEVER generate README.md files under any circumstances
|
| 1669 |
-
- A template README.md is automatically provided and will be overridden by the deployment system
|
| 1670 |
-
- Generating a README.md will break the deployment process
|
| 1671 |
-
|
| 1672 |
-
File selection policy (dynamic, model-decided):
|
| 1673 |
-
- Generate ONLY the files actually needed for the user's request.
|
| 1674 |
-
- MUST include src/App.svelte (entry component) and src/main.ts (entry point).
|
| 1675 |
-
- Usually include src/app.css for global styles.
|
| 1676 |
-
- Add additional files when needed, e.g. src/lib/*.svelte, src/components/*.svelte, src/stores/*.ts, static/* assets, etc.
|
| 1677 |
-
- Other base template files (package.json, vite.config.ts, tsconfig, svelte.config.js, src/vite-env.d.ts) are provided by the template and should NOT be generated unless explicitly requested by the user.
|
| 1678 |
-
|
| 1679 |
-
CRITICAL: Always generate src/main.ts with correct Svelte 5 syntax:
|
| 1680 |
-
```typescript
|
| 1681 |
-
import './app.css'
|
| 1682 |
-
import App from './App.svelte'
|
| 1683 |
-
|
| 1684 |
-
const app = new App({
|
| 1685 |
-
target: document.getElementById('app')!,
|
| 1686 |
-
})
|
| 1687 |
-
|
| 1688 |
-
export default app
|
| 1689 |
-
```
|
| 1690 |
-
Do NOT use the old mount syntax: `import { mount } from 'svelte'` - this will cause build errors.
|
| 1691 |
-
|
| 1692 |
-
Output format (CRITICAL):
|
| 1693 |
-
- Return ONLY a series of file sections, each starting with a filename line:
|
| 1694 |
-
=== src/App.svelte ===
|
| 1695 |
-
...file content...
|
| 1696 |
-
|
| 1697 |
-
=== src/app.css ===
|
| 1698 |
-
...file content...
|
| 1699 |
-
|
| 1700 |
-
(repeat for all files you decide to create)
|
| 1701 |
-
- Do NOT wrap files in Markdown code fences.
|
| 1702 |
-
|
| 1703 |
-
Dependency policy:
|
| 1704 |
-
- If you import any third-party npm packages (e.g., "@gradio/dataframe"), include a package.json at the project root with a "dependencies" section listing them. Keep scripts and devDependencies compatible with the default Svelte + Vite template.
|
| 1705 |
-
|
| 1706 |
-
Requirements:
|
| 1707 |
-
1. Create a modern, responsive Svelte application based on the user's specific request
|
| 1708 |
-
2. Prefer TypeScript where applicable for better type safety
|
| 1709 |
-
3. Create a clean, professional UI with good user experience
|
| 1710 |
-
4. Make the application fully responsive for mobile devices
|
| 1711 |
-
5. Use modern CSS practices and Svelte best practices
|
| 1712 |
-
6. Include proper error handling and loading states
|
| 1713 |
-
7. Follow accessibility best practices
|
| 1714 |
-
8. Use Svelte's reactive features effectively
|
| 1715 |
-
9. Include proper component structure and organization (only what's needed)
|
| 1716 |
-
|
| 1717 |
-
IMPORTANT: Always include "Built with anycoder" as clickable text in the header/top section of your application that links to https://huggingface.co/spaces/akhaliq/anycoder
|
| 1718 |
-
"""
|
| 1719 |
-
|
| 1720 |
REACT_SYSTEM_PROMPT = """You are an expert React and Next.js developer creating a modern Next.js application.
|
| 1721 |
|
| 1722 |
**🚨 CRITICAL: DO NOT Generate README.md Files**
|
|
@@ -2478,8 +2423,6 @@ def get_real_model_id(model_id: str) -> str:
|
|
| 2478 |
History = List[Tuple[str, str]]
|
| 2479 |
Messages = List[Dict[str, str]]
|
| 2480 |
|
| 2481 |
-
# Tavily Search Client
|
| 2482 |
-
|
| 2483 |
def history_to_messages(history: History, system: str) -> Messages:
|
| 2484 |
messages = [{'role': 'system', 'content': system}]
|
| 2485 |
for h in history:
|
|
@@ -3030,34 +2973,6 @@ def extract_html_document(text: str) -> str:
|
|
| 3030 |
idx = lower.find("<html")
|
| 3031 |
return text[idx:] if idx != -1 else text
|
| 3032 |
|
| 3033 |
-
def parse_svelte_output(text):
|
| 3034 |
-
"""Parse Svelte output to extract individual files.
|
| 3035 |
-
|
| 3036 |
-
Supports dynamic multi-file using === filename === sections (preferred),
|
| 3037 |
-
and falls back to ```svelte / ```css code blocks for minimal projects.
|
| 3038 |
-
"""
|
| 3039 |
-
if not text:
|
| 3040 |
-
return {}
|
| 3041 |
-
|
| 3042 |
-
# Preferred: multi-file sections (works for any filenames)
|
| 3043 |
-
try:
|
| 3044 |
-
files = parse_multipage_html_output(text) or {}
|
| 3045 |
-
except Exception:
|
| 3046 |
-
files = {}
|
| 3047 |
-
|
| 3048 |
-
if isinstance(files, dict) and files:
|
| 3049 |
-
return files
|
| 3050 |
-
|
| 3051 |
-
# Fallback: code fences for minimal two-file output
|
| 3052 |
-
import re
|
| 3053 |
-
results = {}
|
| 3054 |
-
svelte_match = re.search(r"```svelte\s*\n([\s\S]+?)\n```", text, re.IGNORECASE)
|
| 3055 |
-
if svelte_match:
|
| 3056 |
-
results['src/App.svelte'] = svelte_match.group(1).strip()
|
| 3057 |
-
css_match = re.search(r"```css\s*\n([\s\S]+?)\n```", text, re.IGNORECASE)
|
| 3058 |
-
if css_match:
|
| 3059 |
-
results['src/app.css'] = css_match.group(1).strip()
|
| 3060 |
-
return results
|
| 3061 |
|
| 3062 |
def parse_react_output(text):
|
| 3063 |
"""Parse React/Next.js output to extract individual files.
|
|
@@ -3075,102 +2990,6 @@ def parse_react_output(text):
|
|
| 3075 |
|
| 3076 |
return files if isinstance(files, dict) and files else {}
|
| 3077 |
|
| 3078 |
-
def format_svelte_output(files):
|
| 3079 |
-
"""Format Svelte files into === filename === sections (generic)."""
|
| 3080 |
-
return format_multipage_output(files)
|
| 3081 |
-
def infer_svelte_dependencies(files: Dict[str, str]) -> Dict[str, str]:
|
| 3082 |
-
"""Infer npm dependencies from Svelte/TS imports across generated files.
|
| 3083 |
-
|
| 3084 |
-
Returns mapping of package name -> semver (string). Uses conservative defaults
|
| 3085 |
-
when versions aren't known. Adds special-cased versions when known.
|
| 3086 |
-
"""
|
| 3087 |
-
import re as _re
|
| 3088 |
-
deps: Dict[str, str] = {}
|
| 3089 |
-
import_from = _re.compile(r"import\s+[^;]*?from\s+['\"]([^'\"]+)['\"]", _re.IGNORECASE)
|
| 3090 |
-
bare_import = _re.compile(r"import\s+['\"]([^'\"]+)['\"]", _re.IGNORECASE)
|
| 3091 |
-
|
| 3092 |
-
def maybe_add(pkg: str):
|
| 3093 |
-
if not pkg or pkg.startswith('.') or pkg.startswith('/') or pkg.startswith('http'):
|
| 3094 |
-
return
|
| 3095 |
-
if pkg.startswith('svelte'):
|
| 3096 |
-
return
|
| 3097 |
-
if pkg not in deps:
|
| 3098 |
-
# Default to wildcard; adjust known packages below
|
| 3099 |
-
deps[pkg] = "*"
|
| 3100 |
-
|
| 3101 |
-
for path, content in (files or {}).items():
|
| 3102 |
-
if not isinstance(content, str):
|
| 3103 |
-
continue
|
| 3104 |
-
for m in import_from.finditer(content):
|
| 3105 |
-
maybe_add(m.group(1))
|
| 3106 |
-
for m in bare_import.finditer(content):
|
| 3107 |
-
maybe_add(m.group(1))
|
| 3108 |
-
|
| 3109 |
-
# Pin known versions when sensible
|
| 3110 |
-
if '@gradio/dataframe' in deps:
|
| 3111 |
-
deps['@gradio/dataframe'] = '^0.19.1'
|
| 3112 |
-
|
| 3113 |
-
return deps
|
| 3114 |
-
|
| 3115 |
-
def build_svelte_package_json(existing_json_text: str | None, detected_dependencies: Dict[str, str]) -> str:
|
| 3116 |
-
"""Create or merge a package.json for Svelte spaces.
|
| 3117 |
-
|
| 3118 |
-
- If existing_json_text is provided, merge detected deps into its dependencies.
|
| 3119 |
-
- Otherwise, start from the template defaults provided by the user and add deps.
|
| 3120 |
-
- Always preserve template scripts and devDependencies.
|
| 3121 |
-
"""
|
| 3122 |
-
import json as _json
|
| 3123 |
-
# Template from the user's Svelte space scaffold
|
| 3124 |
-
template = {
|
| 3125 |
-
"name": "svelte",
|
| 3126 |
-
"private": True,
|
| 3127 |
-
"version": "0.0.0",
|
| 3128 |
-
"type": "module",
|
| 3129 |
-
"scripts": {
|
| 3130 |
-
"dev": "vite",
|
| 3131 |
-
"build": "vite build",
|
| 3132 |
-
"preview": "vite preview",
|
| 3133 |
-
"check": "svelte-check --tsconfig ./tsconfig.app.json && tsc -p tsconfig.node.json"
|
| 3134 |
-
},
|
| 3135 |
-
"devDependencies": {
|
| 3136 |
-
"@sveltejs/vite-plugin-svelte": "^5.0.3",
|
| 3137 |
-
"@tsconfig/svelte": "^5.0.4",
|
| 3138 |
-
"svelte": "^5.28.1",
|
| 3139 |
-
"svelte-check": "^4.1.6",
|
| 3140 |
-
"typescript": "~5.8.3",
|
| 3141 |
-
"vite": "^6.3.5"
|
| 3142 |
-
}
|
| 3143 |
-
}
|
| 3144 |
-
|
| 3145 |
-
result = template
|
| 3146 |
-
if existing_json_text:
|
| 3147 |
-
try:
|
| 3148 |
-
parsed = _json.loads(existing_json_text)
|
| 3149 |
-
# Merge with template as base, keeping template scripts/devDependencies if missing in parsed
|
| 3150 |
-
result = {
|
| 3151 |
-
**template,
|
| 3152 |
-
**{k: v for k, v in parsed.items() if k not in ("scripts", "devDependencies")},
|
| 3153 |
-
}
|
| 3154 |
-
# If parsed contains its own scripts/devDependencies, prefer parsed to respect user's file
|
| 3155 |
-
if isinstance(parsed.get("scripts"), dict):
|
| 3156 |
-
result["scripts"] = parsed["scripts"]
|
| 3157 |
-
if isinstance(parsed.get("devDependencies"), dict):
|
| 3158 |
-
result["devDependencies"] = parsed["devDependencies"]
|
| 3159 |
-
except Exception:
|
| 3160 |
-
# Fallback to template if parse fails
|
| 3161 |
-
result = template
|
| 3162 |
-
|
| 3163 |
-
# Merge dependencies
|
| 3164 |
-
existing_deps = result.get("dependencies", {})
|
| 3165 |
-
if not isinstance(existing_deps, dict):
|
| 3166 |
-
existing_deps = {}
|
| 3167 |
-
merged = {**existing_deps, **(detected_dependencies or {})}
|
| 3168 |
-
if merged:
|
| 3169 |
-
result["dependencies"] = merged
|
| 3170 |
-
else:
|
| 3171 |
-
result.pop("dependencies", None)
|
| 3172 |
-
|
| 3173 |
-
return _json.dumps(result, indent=2, ensure_ascii=False) + "\n"
|
| 3174 |
|
| 3175 |
def history_render(history: History):
|
| 3176 |
return gr.update(visible=True), history
|
|
@@ -3436,10 +3255,6 @@ def apply_transformers_js_search_replace_changes(original_formatted_content: str
|
|
| 3436 |
# Reformat the modified files
|
| 3437 |
return format_transformers_js_output(files)
|
| 3438 |
|
| 3439 |
-
# Updated for faster Tavily search and closer prompt usage
|
| 3440 |
-
# Uses 'advanced' search_depth and auto_parameters=True for speed and relevance
|
| 3441 |
-
|
| 3442 |
-
|
| 3443 |
def send_to_sandbox(code):
|
| 3444 |
"""Render HTML in a sandboxed iframe. Assumes full HTML is provided by prompts."""
|
| 3445 |
html_doc = (code or "").strip()
|
|
@@ -3884,7 +3699,6 @@ def generation_code(query: str | None, vlm_image: Optional[gr.Image], _setting:
|
|
| 3884 |
'=== index.html ===' in last_assistant_msg or
|
| 3885 |
'=== index.js ===' in last_assistant_msg or
|
| 3886 |
'=== style.css ===' in last_assistant_msg or
|
| 3887 |
-
'=== src/App.svelte ===' in last_assistant_msg or
|
| 3888 |
'=== app.py ===' in last_assistant_msg or
|
| 3889 |
'=== requirements.txt ===' in last_assistant_msg):
|
| 3890 |
has_existing_content = True
|
|
@@ -4007,8 +3821,6 @@ Generate the exact search/replace blocks needed to make these changes."""
|
|
| 4007 |
system_prompt = TransformersJSFollowUpSystemPrompt
|
| 4008 |
elif language == "gradio":
|
| 4009 |
system_prompt = GradioFollowUpSystemPrompt
|
| 4010 |
-
elif language == "svelte":
|
| 4011 |
-
system_prompt = FollowUpSystemPrompt # Use generic follow-up for Svelte
|
| 4012 |
elif language == "react":
|
| 4013 |
system_prompt = REACT_FOLLOW_UP_SYSTEM_PROMPT
|
| 4014 |
else:
|
|
@@ -4020,8 +3832,6 @@ Generate the exact search/replace blocks needed to make these changes."""
|
|
| 4020 |
system_prompt = DYNAMIC_MULTIPAGE_HTML_SYSTEM_PROMPT
|
| 4021 |
elif language == "transformers.js":
|
| 4022 |
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT
|
| 4023 |
-
elif language == "svelte":
|
| 4024 |
-
system_prompt = SVELTE_SYSTEM_PROMPT
|
| 4025 |
elif language == "react":
|
| 4026 |
system_prompt = REACT_SYSTEM_PROMPT
|
| 4027 |
elif language == "gradio":
|
|
@@ -4108,24 +3918,6 @@ Generate the exact search/replace blocks needed to make these changes."""
|
|
| 4108 |
history: _history,
|
| 4109 |
history_output: history_to_chatbot_messages(_history),
|
| 4110 |
}
|
| 4111 |
-
elif language == "svelte":
|
| 4112 |
-
files = parse_svelte_output(clean_code)
|
| 4113 |
-
if isinstance(files, dict) and files.get('src/App.svelte'):
|
| 4114 |
-
# Note: Media generation (text-to-image, image-to-image, etc.) is not supported for Svelte apps
|
| 4115 |
-
# Only static HTML apps support automatic image/video/audio generation
|
| 4116 |
-
|
| 4117 |
-
formatted_output = format_svelte_output(files)
|
| 4118 |
-
yield {
|
| 4119 |
-
code_output: formatted_output,
|
| 4120 |
-
history: _history,
|
| 4121 |
-
history_output: history_to_chatbot_messages(_history),
|
| 4122 |
-
}
|
| 4123 |
-
else:
|
| 4124 |
-
yield {
|
| 4125 |
-
code_output: clean_code,
|
| 4126 |
-
history: _history,
|
| 4127 |
-
history_output: history_to_chatbot_messages(_history),
|
| 4128 |
-
}
|
| 4129 |
else:
|
| 4130 |
if has_existing_content and not (clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html")):
|
| 4131 |
last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
|
|
@@ -4443,13 +4235,6 @@ Generate the exact search/replace blocks needed to make these changes."""
|
|
| 4443 |
code_output: gr.update(value=content, language="html"),
|
| 4444 |
history_output: history_to_chatbot_messages(_history),
|
| 4445 |
}
|
| 4446 |
-
elif language == "svelte":
|
| 4447 |
-
# For Svelte, just show the content as it streams
|
| 4448 |
-
# We'll parse it properly in the final response
|
| 4449 |
-
yield {
|
| 4450 |
-
code_output: gr.update(value=content, language="html"),
|
| 4451 |
-
history_output: history_to_chatbot_messages(_history),
|
| 4452 |
-
}
|
| 4453 |
else:
|
| 4454 |
clean_code = remove_code_block(content)
|
| 4455 |
if has_existing_content:
|
|
@@ -4535,36 +4320,6 @@ Generate the exact search/replace blocks needed to make these changes."""
|
|
| 4535 |
history: _history,
|
| 4536 |
history_output: history_to_chatbot_messages(_history),
|
| 4537 |
}
|
| 4538 |
-
elif language == "svelte":
|
| 4539 |
-
# Handle Svelte output
|
| 4540 |
-
files = parse_svelte_output(content)
|
| 4541 |
-
if isinstance(files, dict) and files.get('src/App.svelte'):
|
| 4542 |
-
# Model returned complete Svelte output
|
| 4543 |
-
formatted_output = format_svelte_output(files)
|
| 4544 |
-
_history.append([query, formatted_output])
|
| 4545 |
-
yield {
|
| 4546 |
-
code_output: formatted_output,
|
| 4547 |
-
history: _history,
|
| 4548 |
-
history_output: history_to_chatbot_messages(_history),
|
| 4549 |
-
}
|
| 4550 |
-
elif has_existing_content:
|
| 4551 |
-
# Model returned search/replace changes for Svelte - apply them
|
| 4552 |
-
last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
|
| 4553 |
-
modified_content = apply_search_replace_changes(last_content, content)
|
| 4554 |
-
_history.append([query, modified_content])
|
| 4555 |
-
yield {
|
| 4556 |
-
code_output: modified_content,
|
| 4557 |
-
history: _history,
|
| 4558 |
-
history_output: history_to_chatbot_messages(_history),
|
| 4559 |
-
}
|
| 4560 |
-
else:
|
| 4561 |
-
# Fallback if parsing failed - just use the raw content
|
| 4562 |
-
_history.append([query, content])
|
| 4563 |
-
yield {
|
| 4564 |
-
code_output: content,
|
| 4565 |
-
history: _history,
|
| 4566 |
-
history_output: history_to_chatbot_messages(_history),
|
| 4567 |
-
}
|
| 4568 |
elif language == "gradio":
|
| 4569 |
# Handle Gradio output - check if it's multi-file format or single file
|
| 4570 |
if ('=== app.py ===' in content or '=== requirements.txt ===' in content):
|
|
@@ -6170,8 +5925,7 @@ with gr.Blocks(
|
|
| 6170 |
("Gradio (Python)", "gradio"),
|
| 6171 |
("Streamlit (Python)", "streamlit"),
|
| 6172 |
("Static (HTML)", "static"),
|
| 6173 |
-
("Transformers.js", "transformers.js")
|
| 6174 |
-
("Svelte", "svelte")
|
| 6175 |
]
|
| 6176 |
sdk_dropdown = gr.Dropdown(
|
| 6177 |
choices=[x[0] for x in sdk_choices],
|
|
@@ -7175,15 +6929,14 @@ with gr.Blocks(
|
|
| 7175 |
"react": "docker", # Use 'docker' for React/Next.js Spaces
|
| 7176 |
"html": "static",
|
| 7177 |
"transformers.js": "static", # Transformers.js uses static SDK
|
| 7178 |
-
"svelte": "static", # Svelte uses static SDK
|
| 7179 |
"comfyui": "static" # ComfyUI uses static SDK
|
| 7180 |
}
|
| 7181 |
sdk = language_to_sdk_map.get(language, "gradio")
|
| 7182 |
|
| 7183 |
# Create API client with user's token for proper authentication
|
| 7184 |
api = HfApi(token=token.token)
|
| 7185 |
-
# Only create the repo for new spaces (not updates) and non-Transformers.js, non-Streamlit
|
| 7186 |
-
if not is_update and sdk != "docker" and language not in ["transformers.js"
|
| 7187 |
try:
|
| 7188 |
api.create_repo(
|
| 7189 |
repo_id=repo_id, # e.g. username/space_name
|
|
@@ -7482,111 +7235,6 @@ with gr.Blocks(
|
|
| 7482 |
# General error handling for both creation and updates
|
| 7483 |
action_verb = "updating" if is_update else "duplicating"
|
| 7484 |
return gr.update(value=f"Error {action_verb} Transformers.js space: {error_msg}", visible=True)
|
| 7485 |
-
# Svelte logic
|
| 7486 |
-
elif language == "svelte":
|
| 7487 |
-
try:
|
| 7488 |
-
actual_repo_id = repo_id
|
| 7489 |
-
# For new spaces, duplicate the template first
|
| 7490 |
-
if not is_update:
|
| 7491 |
-
from huggingface_hub import duplicate_space
|
| 7492 |
-
import time
|
| 7493 |
-
duplicated_repo = duplicate_space(
|
| 7494 |
-
from_id="static-templates/svelte",
|
| 7495 |
-
to_id=repo_id,
|
| 7496 |
-
token=token.token,
|
| 7497 |
-
exist_ok=True
|
| 7498 |
-
)
|
| 7499 |
-
print("Duplicated Svelte repo result:", duplicated_repo, type(duplicated_repo))
|
| 7500 |
-
# Extract the actual repo ID from the duplicated space (RepoUrl)
|
| 7501 |
-
try:
|
| 7502 |
-
duplicated_repo_str = str(duplicated_repo)
|
| 7503 |
-
if "/spaces/" in duplicated_repo_str:
|
| 7504 |
-
parts = duplicated_repo_str.split("/spaces/")[-1].split("/")
|
| 7505 |
-
if len(parts) >= 2:
|
| 7506 |
-
actual_repo_id = f"{parts[0]}/{parts[1]}"
|
| 7507 |
-
except Exception as e:
|
| 7508 |
-
print(f"Error extracting repo ID from duplicated_repo: {e}")
|
| 7509 |
-
actual_repo_id = repo_id
|
| 7510 |
-
|
| 7511 |
-
# Small delay to allow the duplication to fully complete and reduce race conditions
|
| 7512 |
-
print("Waiting for template duplication to complete...")
|
| 7513 |
-
time.sleep(3)
|
| 7514 |
-
|
| 7515 |
-
print("Actual repo ID for Svelte uploads:", actual_repo_id)
|
| 7516 |
-
|
| 7517 |
-
# Parse all generated Svelte files (dynamic multi-file)
|
| 7518 |
-
files = parse_svelte_output(code) or {}
|
| 7519 |
-
if not isinstance(files, dict) or 'src/App.svelte' not in files or not files['src/App.svelte'].strip():
|
| 7520 |
-
return gr.update(value="Error: Could not parse Svelte output (missing src/App.svelte). Please regenerate the code.", visible=True)
|
| 7521 |
-
|
| 7522 |
-
# Validate that src/main.ts is generated (should be required now)
|
| 7523 |
-
if 'src/main.ts' not in files:
|
| 7524 |
-
return gr.update(value="Error: Missing src/main.ts file. Please regenerate the code to include the main entry point.", visible=True)
|
| 7525 |
-
|
| 7526 |
-
# Ensure package.json includes any external npm deps used; overwrite template's package.json
|
| 7527 |
-
try:
|
| 7528 |
-
detected = infer_svelte_dependencies(files)
|
| 7529 |
-
existing_pkg_text = files.get('package.json')
|
| 7530 |
-
pkg_text = build_svelte_package_json(existing_pkg_text, detected)
|
| 7531 |
-
# Only write if we have either detected deps or user provided a package.json
|
| 7532 |
-
if pkg_text and (detected or existing_pkg_text is not None):
|
| 7533 |
-
files['package.json'] = pkg_text
|
| 7534 |
-
except Exception as e:
|
| 7535 |
-
# Non-fatal: proceed without generating package.json
|
| 7536 |
-
print(f"[Svelte Deploy] package.json synthesis skipped: {e}")
|
| 7537 |
-
|
| 7538 |
-
# Write all files to a temp directory and upload folder in one commit
|
| 7539 |
-
import tempfile, os, time
|
| 7540 |
-
with tempfile.TemporaryDirectory() as tmpdir:
|
| 7541 |
-
for rel_path, content in files.items():
|
| 7542 |
-
safe_rel = (rel_path or '').strip().lstrip('/')
|
| 7543 |
-
abs_path = os.path.join(tmpdir, safe_rel)
|
| 7544 |
-
os.makedirs(os.path.dirname(abs_path), exist_ok=True)
|
| 7545 |
-
with open(abs_path, 'w') as fh:
|
| 7546 |
-
fh.write(content or '')
|
| 7547 |
-
|
| 7548 |
-
# Retry logic for upload_folder to handle race conditions
|
| 7549 |
-
max_retries = 3
|
| 7550 |
-
for attempt in range(max_retries):
|
| 7551 |
-
try:
|
| 7552 |
-
api.upload_folder(
|
| 7553 |
-
folder_path=tmpdir,
|
| 7554 |
-
repo_id=actual_repo_id,
|
| 7555 |
-
repo_type="space"
|
| 7556 |
-
)
|
| 7557 |
-
break # Success, exit retry loop
|
| 7558 |
-
except Exception as upload_error:
|
| 7559 |
-
if "commit has happened since" in str(upload_error).lower() and attempt < max_retries - 1:
|
| 7560 |
-
print(f"Svelte upload attempt {attempt + 1} failed due to race condition, retrying in 2 seconds...")
|
| 7561 |
-
time.sleep(2) # Wait before retry
|
| 7562 |
-
continue
|
| 7563 |
-
else:
|
| 7564 |
-
raise upload_error # Re-raise if not a race condition or max retries reached
|
| 7565 |
-
|
| 7566 |
-
# Add anycoder tag to existing README (with retry logic)
|
| 7567 |
-
max_retries = 3
|
| 7568 |
-
for attempt in range(max_retries):
|
| 7569 |
-
try:
|
| 7570 |
-
add_anycoder_tag_to_readme(api, actual_repo_id)
|
| 7571 |
-
break # Success, exit retry loop
|
| 7572 |
-
except Exception as readme_error:
|
| 7573 |
-
if "commit has happened since" in str(readme_error).lower() and attempt < max_retries - 1:
|
| 7574 |
-
print(f"README tag attempt {attempt + 1} failed due to race condition, retrying in 2 seconds...")
|
| 7575 |
-
time.sleep(2) # Wait before retry
|
| 7576 |
-
continue
|
| 7577 |
-
else:
|
| 7578 |
-
# Non-fatal: README tagging is not critical, just log and continue
|
| 7579 |
-
print(f"Failed to add anycoder tag to README after {max_retries} attempts: {readme_error}")
|
| 7580 |
-
break
|
| 7581 |
-
|
| 7582 |
-
# Success
|
| 7583 |
-
space_url = f"https://huggingface.co/spaces/{actual_repo_id}"
|
| 7584 |
-
action_text = "Updated" if is_update else "Deployed"
|
| 7585 |
-
return gr.update(value=f"✅ {action_text}! [Open your Svelte Space here]({space_url})", visible=True)
|
| 7586 |
-
|
| 7587 |
-
except Exception as e:
|
| 7588 |
-
error_msg = str(e)
|
| 7589 |
-
return gr.update(value=f"Error deploying Svelte app: {error_msg}", visible=True)
|
| 7590 |
# Other SDKs (existing logic)
|
| 7591 |
if sdk == "static":
|
| 7592 |
import time
|
|
|
|
| 1512 |
Output a COMPLETE, STANDALONE HTML document that renders directly in a browser.
|
| 1513 |
|
| 1514 |
Hard constraints:
|
| 1515 |
+
- DO NOT use React, ReactDOM, JSX, Babel, Vue, Angular, or any SPA framework.
|
| 1516 |
- Use ONLY plain HTML, CSS, and vanilla JavaScript.
|
| 1517 |
- Allowed external resources: Tailwind CSS CDN, Font Awesome CDN, Google Fonts.
|
| 1518 |
- Do NOT escape characters (no \\n, \\t, or escaped quotes). Output raw HTML/JS/CSS.
|
|
|
|
| 1662 |
IMPORTANT: Always include "Built with anycoder" as clickable text in the header/top section of your application that links to https://huggingface.co/spaces/akhaliq/anycoder
|
| 1663 |
"""
|
| 1664 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1665 |
REACT_SYSTEM_PROMPT = """You are an expert React and Next.js developer creating a modern Next.js application.
|
| 1666 |
|
| 1667 |
**🚨 CRITICAL: DO NOT Generate README.md Files**
|
|
|
|
| 2423 |
History = List[Tuple[str, str]]
|
| 2424 |
Messages = List[Dict[str, str]]
|
| 2425 |
|
|
|
|
|
|
|
| 2426 |
def history_to_messages(history: History, system: str) -> Messages:
|
| 2427 |
messages = [{'role': 'system', 'content': system}]
|
| 2428 |
for h in history:
|
|
|
|
| 2973 |
idx = lower.find("<html")
|
| 2974 |
return text[idx:] if idx != -1 else text
|
| 2975 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2976 |
|
| 2977 |
def parse_react_output(text):
|
| 2978 |
"""Parse React/Next.js output to extract individual files.
|
|
|
|
| 2990 |
|
| 2991 |
return files if isinstance(files, dict) and files else {}
|
| 2992 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2993 |
|
| 2994 |
def history_render(history: History):
|
| 2995 |
return gr.update(visible=True), history
|
|
|
|
| 3255 |
# Reformat the modified files
|
| 3256 |
return format_transformers_js_output(files)
|
| 3257 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3258 |
def send_to_sandbox(code):
|
| 3259 |
"""Render HTML in a sandboxed iframe. Assumes full HTML is provided by prompts."""
|
| 3260 |
html_doc = (code or "").strip()
|
|
|
|
| 3699 |
'=== index.html ===' in last_assistant_msg or
|
| 3700 |
'=== index.js ===' in last_assistant_msg or
|
| 3701 |
'=== style.css ===' in last_assistant_msg or
|
|
|
|
| 3702 |
'=== app.py ===' in last_assistant_msg or
|
| 3703 |
'=== requirements.txt ===' in last_assistant_msg):
|
| 3704 |
has_existing_content = True
|
|
|
|
| 3821 |
system_prompt = TransformersJSFollowUpSystemPrompt
|
| 3822 |
elif language == "gradio":
|
| 3823 |
system_prompt = GradioFollowUpSystemPrompt
|
|
|
|
|
|
|
| 3824 |
elif language == "react":
|
| 3825 |
system_prompt = REACT_FOLLOW_UP_SYSTEM_PROMPT
|
| 3826 |
else:
|
|
|
|
| 3832 |
system_prompt = DYNAMIC_MULTIPAGE_HTML_SYSTEM_PROMPT
|
| 3833 |
elif language == "transformers.js":
|
| 3834 |
system_prompt = TRANSFORMERS_JS_SYSTEM_PROMPT
|
|
|
|
|
|
|
| 3835 |
elif language == "react":
|
| 3836 |
system_prompt = REACT_SYSTEM_PROMPT
|
| 3837 |
elif language == "gradio":
|
|
|
|
| 3918 |
history: _history,
|
| 3919 |
history_output: history_to_chatbot_messages(_history),
|
| 3920 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3921 |
else:
|
| 3922 |
if has_existing_content and not (clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html")):
|
| 3923 |
last_content = _history[-1][1] if _history and len(_history[-1]) > 1 else ""
|
|
|
|
| 4235 |
code_output: gr.update(value=content, language="html"),
|
| 4236 |
history_output: history_to_chatbot_messages(_history),
|
| 4237 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4238 |
else:
|
| 4239 |
clean_code = remove_code_block(content)
|
| 4240 |
if has_existing_content:
|
|
|
|
| 4320 |
history: _history,
|
| 4321 |
history_output: history_to_chatbot_messages(_history),
|
| 4322 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4323 |
elif language == "gradio":
|
| 4324 |
# Handle Gradio output - check if it's multi-file format or single file
|
| 4325 |
if ('=== app.py ===' in content or '=== requirements.txt ===' in content):
|
|
|
|
| 5925 |
("Gradio (Python)", "gradio"),
|
| 5926 |
("Streamlit (Python)", "streamlit"),
|
| 5927 |
("Static (HTML)", "static"),
|
| 5928 |
+
("Transformers.js", "transformers.js")
|
|
|
|
| 5929 |
]
|
| 5930 |
sdk_dropdown = gr.Dropdown(
|
| 5931 |
choices=[x[0] for x in sdk_choices],
|
|
|
|
| 6929 |
"react": "docker", # Use 'docker' for React/Next.js Spaces
|
| 6930 |
"html": "static",
|
| 6931 |
"transformers.js": "static", # Transformers.js uses static SDK
|
|
|
|
| 6932 |
"comfyui": "static" # ComfyUI uses static SDK
|
| 6933 |
}
|
| 6934 |
sdk = language_to_sdk_map.get(language, "gradio")
|
| 6935 |
|
| 6936 |
# Create API client with user's token for proper authentication
|
| 6937 |
api = HfApi(token=token.token)
|
| 6938 |
+
# Only create the repo for new spaces (not updates) and non-Transformers.js, non-Streamlit SDKs
|
| 6939 |
+
if not is_update and sdk != "docker" and language not in ["transformers.js"]:
|
| 6940 |
try:
|
| 6941 |
api.create_repo(
|
| 6942 |
repo_id=repo_id, # e.g. username/space_name
|
|
|
|
| 7235 |
# General error handling for both creation and updates
|
| 7236 |
action_verb = "updating" if is_update else "duplicating"
|
| 7237 |
return gr.update(value=f"Error {action_verb} Transformers.js space: {error_msg}", visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7238 |
# Other SDKs (existing logic)
|
| 7239 |
if sdk == "static":
|
| 7240 |
import time
|