Spaces:
Running
Running
support more languages
Browse files
app.py
CHANGED
@@ -21,13 +21,21 @@ import gradio as gr
|
|
21 |
from huggingface_hub import InferenceClient
|
22 |
from tavily import TavilyClient
|
23 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
# Search/Replace Constants
|
25 |
SEARCH_START = "<<<<<<< SEARCH"
|
26 |
DIVIDER = "======="
|
27 |
REPLACE_END = ">>>>>>> REPLACE"
|
28 |
|
29 |
# Configuration
|
30 |
-
|
31 |
|
32 |
For website redesign tasks:
|
33 |
- Use the provided original HTML code as the starting point for redesign
|
@@ -46,8 +54,10 @@ Always respond with code that can be executed or rendered directly.
|
|
46 |
|
47 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text."""
|
48 |
|
|
|
|
|
49 |
# System prompt with search capability
|
50 |
-
|
51 |
|
52 |
You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies.
|
53 |
|
@@ -69,6 +79,10 @@ Always respond with code that can be executed or rendered directly.
|
|
69 |
|
70 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text."""
|
71 |
|
|
|
|
|
|
|
|
|
72 |
# Follow-up system prompt for modifying existing HTML files
|
73 |
FollowUpSystemPrompt = f"""You are an expert web developer modifying an existing HTML file.
|
74 |
The user wants to apply changes based on their request.
|
@@ -926,7 +940,7 @@ The HTML code above contains the complete original website structure with all im
|
|
926 |
except Exception as e:
|
927 |
return f"Error extracting website content: {str(e)}"
|
928 |
|
929 |
-
def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optional[str], website_url: Optional[str], _setting: Dict[str, str], _history: Optional[History], _current_model: Dict, enable_search: bool = False):
|
930 |
if query is None:
|
931 |
query = ''
|
932 |
if _history is None:
|
@@ -945,8 +959,11 @@ def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optio
|
|
945 |
# Use follow-up prompt for modifying existing HTML
|
946 |
system_prompt = FollowUpSystemPrompt
|
947 |
else:
|
948 |
-
# Use
|
949 |
-
|
|
|
|
|
|
|
950 |
|
951 |
messages = history_to_messages(_history, system_prompt)
|
952 |
|
@@ -1005,24 +1022,24 @@ This will help me create a better design for you."""
|
|
1005 |
# Fallback: If the model returns a full HTML file, use it directly
|
1006 |
if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
|
1007 |
yield {
|
1008 |
-
code_output: clean_code,
|
1009 |
history_output: history_to_chatbot_messages(_history),
|
1010 |
-
sandbox: send_to_sandbox(clean_code),
|
1011 |
}
|
1012 |
else:
|
1013 |
last_html = _history[-1][1] if _history else ""
|
1014 |
modified_html = apply_search_replace_changes(last_html, clean_code)
|
1015 |
clean_html = remove_code_block(modified_html)
|
1016 |
yield {
|
1017 |
-
code_output: clean_html,
|
1018 |
history_output: history_to_chatbot_messages(_history),
|
1019 |
-
sandbox: send_to_sandbox(clean_html),
|
1020 |
}
|
1021 |
else:
|
1022 |
yield {
|
1023 |
-
code_output: clean_code,
|
1024 |
history_output: history_to_chatbot_messages(_history),
|
1025 |
-
sandbox: send_to_sandbox(clean_code),
|
1026 |
}
|
1027 |
# Handle response based on whether this is a modification or new generation
|
1028 |
if has_existing_html:
|
@@ -1080,7 +1097,7 @@ with gr.Blocks(
|
|
1080 |
) as demo:
|
1081 |
history = gr.State([])
|
1082 |
setting = gr.State({
|
1083 |
-
"system":
|
1084 |
})
|
1085 |
current_model = gr.State(AVAILABLE_MODELS[0]) # Moonshot Kimi-K2
|
1086 |
open_panel = gr.State(None)
|
@@ -1100,6 +1117,16 @@ with gr.Blocks(
|
|
1100 |
lines=3,
|
1101 |
visible=False
|
1102 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1103 |
website_url_input = gr.Textbox(
|
1104 |
label="Website URL for redesign",
|
1105 |
placeholder="https://example.com",
|
@@ -1160,7 +1187,7 @@ with gr.Blocks(
|
|
1160 |
)
|
1161 |
with gr.Accordion("Advanced", open=False, visible=False) as advanced_accordion:
|
1162 |
systemPromptInput = gr.Textbox(
|
1163 |
-
value=
|
1164 |
label="System prompt",
|
1165 |
lines=5
|
1166 |
)
|
@@ -1174,7 +1201,7 @@ with gr.Blocks(
|
|
1174 |
logged_in = label.startswith("Logout (")
|
1175 |
# Only update if state changes
|
1176 |
if last_state == logged_in:
|
1177 |
-
return [gr.skip()] *
|
1178 |
return (
|
1179 |
logged_in, # login_state
|
1180 |
gr.update(visible=not logged_in), # login_required_msg
|
@@ -1188,11 +1215,12 @@ with gr.Blocks(
|
|
1188 |
gr.update(visible=logged_in), # quick_examples_col
|
1189 |
gr.update(visible=logged_in), # advanced_accordion
|
1190 |
logged_in, # update last_login_state
|
|
|
1191 |
)
|
1192 |
timer.tick(
|
1193 |
fn=check_login,
|
1194 |
inputs=[login_button, last_login_state],
|
1195 |
-
outputs=[login_state, login_required_msg, input, website_url_input, file_input, btn, clear_btn, search_toggle, model_dropdown, quick_examples_col, advanced_accordion, last_login_state]
|
1196 |
)
|
1197 |
|
1198 |
with gr.Column():
|
@@ -1210,11 +1238,25 @@ with gr.Blocks(
|
|
1210 |
history_output = gr.Chatbot(show_label=False, height=400, type="messages")
|
1211 |
|
1212 |
# Event handlers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1213 |
btn.click(
|
1214 |
generation_code,
|
1215 |
-
inputs=[input, image_input, file_input, website_url_input, setting, history, current_model, search_toggle],
|
1216 |
outputs=[code_output, history, sandbox, history_output]
|
1217 |
)
|
|
|
|
|
|
|
1218 |
clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
|
1219 |
|
1220 |
if __name__ == "__main__":
|
|
|
21 |
from huggingface_hub import InferenceClient
|
22 |
from tavily import TavilyClient
|
23 |
|
24 |
+
# Gradio supported languages for syntax highlighting
|
25 |
+
GRADIO_SUPPORTED_LANGUAGES = [
|
26 |
+
"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", None
|
27 |
+
]
|
28 |
+
|
29 |
+
def get_gradio_language(language):
|
30 |
+
return language if language in GRADIO_SUPPORTED_LANGUAGES else None
|
31 |
+
|
32 |
# Search/Replace Constants
|
33 |
SEARCH_START = "<<<<<<< SEARCH"
|
34 |
DIVIDER = "======="
|
35 |
REPLACE_END = ">>>>>>> REPLACE"
|
36 |
|
37 |
# Configuration
|
38 |
+
HTML_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 FILE
|
39 |
|
40 |
For website redesign tasks:
|
41 |
- Use the provided original HTML code as the starting point for redesign
|
|
|
54 |
|
55 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text."""
|
56 |
|
57 |
+
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 ```{language} ... ``` 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."""
|
58 |
+
|
59 |
# System prompt with search capability
|
60 |
+
HTML_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 FILE
|
61 |
|
62 |
You have access to real-time web search. When needed, use web search to find the latest information, best practices, or specific technologies.
|
63 |
|
|
|
79 |
|
80 |
Always output only the HTML code inside a ```html ... ``` code block, and do not include any explanations or extra text."""
|
81 |
|
82 |
+
GENERIC_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}.
|
83 |
+
|
84 |
+
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 ```{language} ... ``` 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."""
|
85 |
+
|
86 |
# Follow-up system prompt for modifying existing HTML files
|
87 |
FollowUpSystemPrompt = f"""You are an expert web developer modifying an existing HTML file.
|
88 |
The user wants to apply changes based on their request.
|
|
|
940 |
except Exception as e:
|
941 |
return f"Error extracting website content: {str(e)}"
|
942 |
|
943 |
+
def generation_code(query: Optional[str], image: Optional[gr.Image], file: Optional[str], website_url: Optional[str], _setting: Dict[str, str], _history: Optional[History], _current_model: Dict, enable_search: bool = False, language: str = "html"):
|
944 |
if query is None:
|
945 |
query = ''
|
946 |
if _history is None:
|
|
|
959 |
# Use follow-up prompt for modifying existing HTML
|
960 |
system_prompt = FollowUpSystemPrompt
|
961 |
else:
|
962 |
+
# Use language-specific prompt
|
963 |
+
if language == "html":
|
964 |
+
system_prompt = HTML_SYSTEM_PROMPT_WITH_SEARCH if enable_search else HTML_SYSTEM_PROMPT
|
965 |
+
else:
|
966 |
+
system_prompt = GENERIC_SYSTEM_PROMPT_WITH_SEARCH.format(language=language) if enable_search else GENERIC_SYSTEM_PROMPT.format(language=language)
|
967 |
|
968 |
messages = history_to_messages(_history, system_prompt)
|
969 |
|
|
|
1022 |
# Fallback: If the model returns a full HTML file, use it directly
|
1023 |
if clean_code.strip().startswith("<!DOCTYPE html>") or clean_code.strip().startswith("<html"):
|
1024 |
yield {
|
1025 |
+
code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
|
1026 |
history_output: history_to_chatbot_messages(_history),
|
1027 |
+
sandbox: send_to_sandbox(clean_code) if language == "html" else "<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>",
|
1028 |
}
|
1029 |
else:
|
1030 |
last_html = _history[-1][1] if _history else ""
|
1031 |
modified_html = apply_search_replace_changes(last_html, clean_code)
|
1032 |
clean_html = remove_code_block(modified_html)
|
1033 |
yield {
|
1034 |
+
code_output: gr.update(value=clean_html, language=get_gradio_language(language)),
|
1035 |
history_output: history_to_chatbot_messages(_history),
|
1036 |
+
sandbox: send_to_sandbox(clean_html) if language == "html" else "<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>",
|
1037 |
}
|
1038 |
else:
|
1039 |
yield {
|
1040 |
+
code_output: gr.update(value=clean_code, language=get_gradio_language(language)),
|
1041 |
history_output: history_to_chatbot_messages(_history),
|
1042 |
+
sandbox: send_to_sandbox(clean_code) if language == "html" else "<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>",
|
1043 |
}
|
1044 |
# Handle response based on whether this is a modification or new generation
|
1045 |
if has_existing_html:
|
|
|
1097 |
) as demo:
|
1098 |
history = gr.State([])
|
1099 |
setting = gr.State({
|
1100 |
+
"system": HTML_SYSTEM_PROMPT,
|
1101 |
})
|
1102 |
current_model = gr.State(AVAILABLE_MODELS[0]) # Moonshot Kimi-K2
|
1103 |
open_panel = gr.State(None)
|
|
|
1117 |
lines=3,
|
1118 |
visible=False
|
1119 |
)
|
1120 |
+
# Language dropdown for code generation
|
1121 |
+
language_choices = [
|
1122 |
+
"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"
|
1123 |
+
]
|
1124 |
+
language_dropdown = gr.Dropdown(
|
1125 |
+
choices=language_choices,
|
1126 |
+
value="html",
|
1127 |
+
label="Code Language",
|
1128 |
+
visible=False
|
1129 |
+
)
|
1130 |
website_url_input = gr.Textbox(
|
1131 |
label="Website URL for redesign",
|
1132 |
placeholder="https://example.com",
|
|
|
1187 |
)
|
1188 |
with gr.Accordion("Advanced", open=False, visible=False) as advanced_accordion:
|
1189 |
systemPromptInput = gr.Textbox(
|
1190 |
+
value=HTML_SYSTEM_PROMPT,
|
1191 |
label="System prompt",
|
1192 |
lines=5
|
1193 |
)
|
|
|
1201 |
logged_in = label.startswith("Logout (")
|
1202 |
# Only update if state changes
|
1203 |
if last_state == logged_in:
|
1204 |
+
return [gr.skip()] * 13 # skip updating all outputs
|
1205 |
return (
|
1206 |
logged_in, # login_state
|
1207 |
gr.update(visible=not logged_in), # login_required_msg
|
|
|
1215 |
gr.update(visible=logged_in), # quick_examples_col
|
1216 |
gr.update(visible=logged_in), # advanced_accordion
|
1217 |
logged_in, # update last_login_state
|
1218 |
+
gr.update(visible=logged_in), # language_dropdown
|
1219 |
)
|
1220 |
timer.tick(
|
1221 |
fn=check_login,
|
1222 |
inputs=[login_button, last_login_state],
|
1223 |
+
outputs=[login_state, login_required_msg, input, website_url_input, file_input, btn, clear_btn, search_toggle, model_dropdown, quick_examples_col, advanced_accordion, last_login_state, language_dropdown]
|
1224 |
)
|
1225 |
|
1226 |
with gr.Column():
|
|
|
1238 |
history_output = gr.Chatbot(show_label=False, height=400, type="messages")
|
1239 |
|
1240 |
# Event handlers
|
1241 |
+
def update_code_language(language):
|
1242 |
+
return gr.update(language=get_gradio_language(language))
|
1243 |
+
|
1244 |
+
language_dropdown.change(update_code_language, inputs=language_dropdown, outputs=code_output)
|
1245 |
+
|
1246 |
+
def preview_logic(code, language):
|
1247 |
+
if language == "html":
|
1248 |
+
return send_to_sandbox(code)
|
1249 |
+
else:
|
1250 |
+
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>"
|
1251 |
+
|
1252 |
btn.click(
|
1253 |
generation_code,
|
1254 |
+
inputs=[input, image_input, file_input, website_url_input, setting, history, current_model, search_toggle, language_dropdown],
|
1255 |
outputs=[code_output, history, sandbox, history_output]
|
1256 |
)
|
1257 |
+
# Update preview when code or language changes
|
1258 |
+
code_output.change(preview_logic, inputs=[code_output, language_dropdown], outputs=sandbox)
|
1259 |
+
language_dropdown.change(preview_logic, inputs=[code_output, language_dropdown], outputs=sandbox)
|
1260 |
clear_btn.click(clear_history, outputs=[history, history_output, file_input, website_url_input])
|
1261 |
|
1262 |
if __name__ == "__main__":
|