Spaces:
Running
Running
add glm 4.5
Browse files
app.py
CHANGED
@@ -48,7 +48,16 @@ DIVIDER = "======="
|
|
48 |
REPLACE_END = ">>>>>>> REPLACE"
|
49 |
|
50 |
# Configuration
|
51 |
-
HTML_SYSTEM_PROMPT = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
52 |
|
53 |
For website redesign tasks:
|
54 |
- Use the provided original HTML code as the starting point for redesign
|
@@ -67,6 +76,19 @@ Always respond with code that can be executed or rendered directly.
|
|
67 |
|
68 |
Always 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."""
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
TRANSFORMERS_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.
|
71 |
|
72 |
IMPORTANT: You MUST output ALL THREE files in the following format:
|
@@ -207,9 +229,16 @@ Always output only the three code blocks as shown above, and do not include any
|
|
207 |
GENERIC_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."""
|
208 |
|
209 |
# System prompt with search capability
|
210 |
-
HTML_SYSTEM_PROMPT_WITH_SEARCH = """
|
211 |
|
212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
213 |
|
214 |
For website redesign tasks:
|
215 |
- Use the provided original HTML code as the starting point for redesign
|
@@ -421,6 +450,11 @@ AVAILABLE_MODELS = [
|
|
421 |
"id": "zai-org/GLM-4.5",
|
422 |
"description": "GLM-4.5 model with thinking capabilities for advanced code generation"
|
423 |
},
|
|
|
|
|
|
|
|
|
|
|
424 |
{
|
425 |
"name": "GLM-4.1V-9B-Thinking",
|
426 |
"id": "THUDM/GLM-4.1V-9B-Thinking",
|
@@ -1006,7 +1040,8 @@ def update_image_input_visibility(model):
|
|
1006 |
"""Update image input visibility based on selected model"""
|
1007 |
is_ernie_vl = model.get("id") == "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT"
|
1008 |
is_glm_vl = model.get("id") == "THUDM/GLM-4.1V-9B-Thinking"
|
1009 |
-
|
|
|
1010 |
|
1011 |
def process_image_for_model(image):
|
1012 |
"""Convert image to base64 for model input"""
|
@@ -1680,37 +1715,9 @@ Please use the search results above to help create the requested application wit
|
|
1680 |
return enhanced_query
|
1681 |
|
1682 |
def send_to_sandbox(code):
|
1683 |
-
|
1684 |
-
|
1685 |
-
|
1686 |
-
<html>
|
1687 |
-
<head>
|
1688 |
-
<meta charset=\"UTF-8\">
|
1689 |
-
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">
|
1690 |
-
<script>
|
1691 |
-
// Safe localStorage polyfill
|
1692 |
-
const safeStorage = {{
|
1693 |
-
_data: {{}},
|
1694 |
-
getItem: function(key) {{ return this._data[key] || null; }},
|
1695 |
-
setItem: function(key, value) {{ this._data[key] = value; }},
|
1696 |
-
removeItem: function(key) {{ delete this._data[key]; }},
|
1697 |
-
clear: function() {{ this._data = {{}}; }}
|
1698 |
-
}};
|
1699 |
-
Object.defineProperty(window, 'localStorage', {{
|
1700 |
-
value: safeStorage,
|
1701 |
-
writable: false
|
1702 |
-
}});
|
1703 |
-
window.onerror = function(message, source, lineno, colno, error) {{
|
1704 |
-
console.error('Error:', message);
|
1705 |
-
}};
|
1706 |
-
</script>
|
1707 |
-
</head>
|
1708 |
-
<body>
|
1709 |
-
{code}
|
1710 |
-
</body>
|
1711 |
-
</html>
|
1712 |
-
"""
|
1713 |
-
encoded_html = base64.b64encode(wrapped_code.encode('utf-8')).decode('utf-8')
|
1714 |
data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
|
1715 |
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>'
|
1716 |
return iframe
|
@@ -2540,6 +2547,91 @@ This will help me create a better design for you."""
|
|
2540 |
}
|
2541 |
return
|
2542 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2543 |
# Use dynamic client based on selected model (for non-GLM-4.5 models)
|
2544 |
client = get_inference_client(_current_model["id"], provider)
|
2545 |
|
|
|
48 |
REPLACE_END = ">>>>>>> REPLACE"
|
49 |
|
50 |
# Configuration
|
51 |
+
HTML_SYSTEM_PROMPT = """You are an expert front-end developer.
|
52 |
+
|
53 |
+
Output a COMPLETE, STANDALONE HTML document that renders directly in a browser. Requirements:
|
54 |
+
- Include <!DOCTYPE html>, <html>, <head>, and <body> with proper nesting
|
55 |
+
- Include all required <link> and <script> tags for any libraries you use
|
56 |
+
- Do NOT escape characters (no \\n, \\t, or escaped quotes). Output raw HTML/JS/CSS.
|
57 |
+
- If you use React or Tailwind, include correct CDN tags
|
58 |
+
- Keep everything in ONE file; inline CSS/JS as needed
|
59 |
+
|
60 |
+
For website redesign tasks:
|
61 |
|
62 |
For website redesign tasks:
|
63 |
- Use the provided original HTML code as the starting point for redesign
|
|
|
76 |
|
77 |
Always 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."""
|
78 |
|
79 |
+
# Stricter prompt for GLM-4.5V to ensure a complete, runnable HTML document with no escaped characters
|
80 |
+
GLM45V_HTML_SYSTEM_PROMPT = """You are an expert front-end developer.
|
81 |
+
|
82 |
+
Output a COMPLETE, STANDALONE HTML document that renders directly in a browser. Requirements:
|
83 |
+
- Include <!DOCTYPE html>, <html>, <head>, and <body> with proper nesting
|
84 |
+
- Include all required <link> and <script> tags for any libraries you use
|
85 |
+
- Do NOT escape characters (no \\n, \\t, or escaped quotes). Output raw HTML/JS/CSS.
|
86 |
+
- If you use React or Tailwind, include correct CDN tags
|
87 |
+
- Keep everything in ONE file; inline CSS/JS as needed
|
88 |
+
|
89 |
+
Return ONLY the code inside a single ```html ... ``` code block. No additional text before or after.
|
90 |
+
"""
|
91 |
+
|
92 |
TRANSFORMERS_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.
|
93 |
|
94 |
IMPORTANT: You MUST output ALL THREE files in the following format:
|
|
|
229 |
GENERIC_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."""
|
230 |
|
231 |
# System prompt with search capability
|
232 |
+
HTML_SYSTEM_PROMPT_WITH_SEARCH = """You are an expert front-end developer. You have access to real-time web search.
|
233 |
|
234 |
+
Output a COMPLETE, STANDALONE HTML document that renders directly in a browser. Requirements:
|
235 |
+
- Include <!DOCTYPE html>, <html>, <head>, and <body> with proper nesting
|
236 |
+
- Include all required <link> and <script> tags for any libraries you use
|
237 |
+
- Do NOT escape characters (no \\n, \\t, or escaped quotes). Output raw HTML/JS/CSS.
|
238 |
+
- If you use React or Tailwind, include correct CDN tags
|
239 |
+
- Keep everything in ONE file; inline CSS/JS as needed
|
240 |
+
|
241 |
+
Use web search when needed to find the latest best practices or correct CDN links.
|
242 |
|
243 |
For website redesign tasks:
|
244 |
- Use the provided original HTML code as the starting point for redesign
|
|
|
450 |
"id": "zai-org/GLM-4.5",
|
451 |
"description": "GLM-4.5 model with thinking capabilities for advanced code generation"
|
452 |
},
|
453 |
+
{
|
454 |
+
"name": "GLM-4.5V",
|
455 |
+
"id": "zai-org/GLM-4.5V",
|
456 |
+
"description": "GLM-4.5V multimodal model with image understanding for code generation"
|
457 |
+
},
|
458 |
{
|
459 |
"name": "GLM-4.1V-9B-Thinking",
|
460 |
"id": "THUDM/GLM-4.1V-9B-Thinking",
|
|
|
1040 |
"""Update image input visibility based on selected model"""
|
1041 |
is_ernie_vl = model.get("id") == "baidu/ERNIE-4.5-VL-424B-A47B-Base-PT"
|
1042 |
is_glm_vl = model.get("id") == "THUDM/GLM-4.1V-9B-Thinking"
|
1043 |
+
is_glm_45v = model.get("id") == "zai-org/GLM-4.5V"
|
1044 |
+
return gr.update(visible=is_ernie_vl or is_glm_vl or is_glm_45v)
|
1045 |
|
1046 |
def process_image_for_model(image):
|
1047 |
"""Convert image to base64 for model input"""
|
|
|
1715 |
return enhanced_query
|
1716 |
|
1717 |
def send_to_sandbox(code):
|
1718 |
+
"""Render HTML in a sandboxed iframe. Assumes full HTML is provided by prompts."""
|
1719 |
+
html_doc = (code or "").strip()
|
1720 |
+
encoded_html = base64.b64encode(html_doc.encode('utf-8')).decode('utf-8')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1721 |
data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
|
1722 |
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>'
|
1723 |
return iframe
|
|
|
2547 |
}
|
2548 |
return
|
2549 |
|
2550 |
+
# Handle GLM-4.5V (multimodal vision)
|
2551 |
+
if _current_model["id"] == "zai-org/GLM-4.5V":
|
2552 |
+
# Build structured messages with a strong system prompt to enforce full HTML output
|
2553 |
+
structured = [
|
2554 |
+
{"role": "system", "content": GLM45V_HTML_SYSTEM_PROMPT}
|
2555 |
+
]
|
2556 |
+
if image is not None:
|
2557 |
+
user_msg = {
|
2558 |
+
"role": "user",
|
2559 |
+
"content": [
|
2560 |
+
{"type": "text", "text": enhanced_query},
|
2561 |
+
],
|
2562 |
+
}
|
2563 |
+
try:
|
2564 |
+
import io, base64
|
2565 |
+
from PIL import Image
|
2566 |
+
import numpy as np
|
2567 |
+
if isinstance(image, np.ndarray):
|
2568 |
+
image = Image.fromarray(image)
|
2569 |
+
buf = io.BytesIO()
|
2570 |
+
image.save(buf, format="PNG")
|
2571 |
+
b64 = base64.b64encode(buf.getvalue()).decode()
|
2572 |
+
user_msg["content"].append({
|
2573 |
+
"type": "image_url",
|
2574 |
+
"image_url": {"url": f"data:image/png;base64,{b64}"}
|
2575 |
+
})
|
2576 |
+
structured.append(user_msg)
|
2577 |
+
except Exception:
|
2578 |
+
structured.append({"role": "user", "content": enhanced_query})
|
2579 |
+
else:
|
2580 |
+
structured.append({"role": "user", "content": enhanced_query})
|
2581 |
+
|
2582 |
+
try:
|
2583 |
+
client = InferenceClient(
|
2584 |
+
provider="auto",
|
2585 |
+
api_key=os.environ["HF_TOKEN"],
|
2586 |
+
bill_to="huggingface",
|
2587 |
+
)
|
2588 |
+
stream = client.chat.completions.create(
|
2589 |
+
model="zai-org/GLM-4.5V",
|
2590 |
+
messages=structured,
|
2591 |
+
stream=True,
|
2592 |
+
)
|
2593 |
+
content = ""
|
2594 |
+
for chunk in stream:
|
2595 |
+
if getattr(chunk, "choices", None) and chunk.choices and getattr(chunk.choices[0], "delta", None) and getattr(chunk.choices[0].delta, "content", None):
|
2596 |
+
content += chunk.choices[0].delta.content
|
2597 |
+
clean_code = remove_code_block(content)
|
2598 |
+
# Ensure escaped newlines/tabs from model are rendered correctly
|
2599 |
+
if "\\n" in clean_code:
|
2600 |
+
clean_code = clean_code.replace("\\n", "\n")
|
2601 |
+
if "\\t" in clean_code:
|
2602 |
+
clean_code = clean_code.replace("\\t", "\t")
|
2603 |
+
preview_val = None
|
2604 |
+
if language == "html":
|
2605 |
+
preview_val = send_to_sandbox(clean_code)
|
2606 |
+
elif language == "python" and is_streamlit_code(clean_code):
|
2607 |
+
preview_val = send_streamlit_to_stlite(clean_code)
|
2608 |
+
yield {
|
2609 |
+
code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
|
2610 |
+
history_output: history_to_chatbot_messages(_history),
|
2611 |
+
sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
|
2612 |
+
}
|
2613 |
+
except Exception as e:
|
2614 |
+
content = f"Error with GLM-4.5V: {str(e)}\n\nPlease make sure HF_TOKEN environment variable is set."
|
2615 |
+
|
2616 |
+
clean_code = remove_code_block(content)
|
2617 |
+
if "\\n" in clean_code:
|
2618 |
+
clean_code = clean_code.replace("\\n", "\n")
|
2619 |
+
if "\\t" in clean_code:
|
2620 |
+
clean_code = clean_code.replace("\\t", "\t")
|
2621 |
+
_history.append([query, clean_code])
|
2622 |
+
preview_val = None
|
2623 |
+
if language == "html":
|
2624 |
+
preview_val = send_to_sandbox(clean_code)
|
2625 |
+
elif language == "python" and is_streamlit_code(clean_code):
|
2626 |
+
preview_val = send_streamlit_to_stlite(clean_code)
|
2627 |
+
yield {
|
2628 |
+
code_output: clean_code,
|
2629 |
+
history: _history,
|
2630 |
+
sandbox: preview_val or "<div style='padding:1em;color:#888;text-align:center;'>Preview is only available for HTML or Streamlit-in-Python.</div>",
|
2631 |
+
history_output: history_to_chatbot_messages(_history),
|
2632 |
+
}
|
2633 |
+
return
|
2634 |
+
|
2635 |
# Use dynamic client based on selected model (for non-GLM-4.5 models)
|
2636 |
client = get_inference_client(_current_model["id"], provider)
|
2637 |
|