Spaces:
Running
Running
feat: add code playground tab
Browse files
app.py
CHANGED
@@ -5,6 +5,7 @@ import mimetypes
|
|
5 |
import os
|
6 |
import requests
|
7 |
import time
|
|
|
8 |
import modelscope_studio.components.antd as antd
|
9 |
import modelscope_studio.components.antdx as antdx
|
10 |
import modelscope_studio.components.base as ms
|
@@ -12,6 +13,8 @@ import modelscope_studio.components.pro as pro
|
|
12 |
from modelscope_studio.components.pro.chatbot import (
|
13 |
ChatbotActionConfig, ChatbotBotConfig, ChatbotMarkdownConfig,
|
14 |
ChatbotPromptsConfig, ChatbotUserConfig, ChatbotWelcomeConfig)
|
|
|
|
|
15 |
|
16 |
|
17 |
MODEL_VERSION = os.environ['MODEL_VERSION']
|
@@ -282,75 +285,369 @@ def submit(sender_value, chatbot_value):
|
|
282 |
raise e
|
283 |
|
284 |
|
285 |
-
|
286 |
-
with
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
327 |
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
|
334 |
-
clear_btn.click(fn=clear, outputs=[chatbot])
|
335 |
-
submit_event = sender.submit(
|
336 |
-
fn=submit,
|
337 |
-
inputs=[sender, chatbot],
|
338 |
-
outputs=[sender, chatbot, clear_btn]
|
339 |
-
)
|
340 |
-
sender.cancel(
|
341 |
-
fn=cancel,
|
342 |
-
inputs=[chatbot],
|
343 |
-
outputs=[chatbot, sender, clear_btn],
|
344 |
-
cancels=[submit_event],
|
345 |
-
queue=False
|
346 |
-
)
|
347 |
-
chatbot.retry(
|
348 |
-
fn=retry,
|
349 |
-
inputs=[chatbot],
|
350 |
-
outputs=[sender, chatbot, clear_btn]
|
351 |
-
)
|
352 |
-
chatbot.welcome_prompt_select(fn=prompt_select, outputs=[sender])
|
353 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
354 |
|
355 |
if __name__ == '__main__':
|
356 |
-
demo.queue(default_concurrency_limit=50).launch()
|
|
|
5 |
import os
|
6 |
import requests
|
7 |
import time
|
8 |
+
import modelscope_studio.components.legacy as legacy
|
9 |
import modelscope_studio.components.antd as antd
|
10 |
import modelscope_studio.components.antdx as antdx
|
11 |
import modelscope_studio.components.base as ms
|
|
|
13 |
from modelscope_studio.components.pro.chatbot import (
|
14 |
ChatbotActionConfig, ChatbotBotConfig, ChatbotMarkdownConfig,
|
15 |
ChatbotPromptsConfig, ChatbotUserConfig, ChatbotWelcomeConfig)
|
16 |
+
from config import DEFAULT_PROMPTS, EXAMPLES, SystemPrompt
|
17 |
+
import re
|
18 |
|
19 |
|
20 |
MODEL_VERSION = os.environ['MODEL_VERSION']
|
|
|
285 |
raise e
|
286 |
|
287 |
|
288 |
+
def remove_code_block(text):
|
289 |
+
# Try to match code blocks with language markers
|
290 |
+
patterns = [
|
291 |
+
r'```(?:html|HTML)\n([\s\S]+?)\n```', # Match ```html or ```HTML
|
292 |
+
r'```\n([\s\S]+?)\n```', # Match code blocks without language markers
|
293 |
+
r'```([\s\S]+?)```' # Match code blocks without line breaks
|
294 |
+
]
|
295 |
+
|
296 |
+
for pattern in patterns:
|
297 |
+
match = re.search(pattern, text, re.DOTALL)
|
298 |
+
if match:
|
299 |
+
extracted = match.group(1).strip()
|
300 |
+
print("Successfully extracted code block:", extracted)
|
301 |
+
return extracted
|
302 |
+
|
303 |
+
# If no code block is found, check if the entire text is HTML
|
304 |
+
if text.strip().startswith('<!DOCTYPE html>') or text.strip().startswith('<html'):
|
305 |
+
print("Text appears to be raw HTML, using as is")
|
306 |
+
return text.strip()
|
307 |
+
|
308 |
+
print("No code block found in text:", text)
|
309 |
+
return text.strip()
|
310 |
+
|
311 |
+
def send_to_sandbox(code):
|
312 |
+
# Add a wrapper to inject necessary permissions
|
313 |
+
wrapped_code = f"""
|
314 |
+
<!DOCTYPE html>
|
315 |
+
<html>
|
316 |
+
<head>
|
317 |
+
<meta charset="UTF-8">
|
318 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
319 |
+
<script>
|
320 |
+
// Create a safe storage alternative
|
321 |
+
const safeStorage = {{
|
322 |
+
_data: {{}},
|
323 |
+
getItem: function(key) {{
|
324 |
+
return this._data[key] || null;
|
325 |
+
}},
|
326 |
+
setItem: function(key, value) {{
|
327 |
+
this._data[key] = value;
|
328 |
+
}},
|
329 |
+
removeItem: function(key) {{
|
330 |
+
delete this._data[key];
|
331 |
+
}},
|
332 |
+
clear: function() {{
|
333 |
+
this._data = {{}};
|
334 |
+
}}
|
335 |
+
}};
|
336 |
+
|
337 |
+
// Replace native localStorage
|
338 |
+
Object.defineProperty(window, 'localStorage', {{
|
339 |
+
value: safeStorage,
|
340 |
+
writable: false
|
341 |
+
}});
|
342 |
+
|
343 |
+
// Add error handling without using alert
|
344 |
+
window.onerror = function(message, source, lineno, colno, error) {{
|
345 |
+
console.error('Error:', message);
|
346 |
+
}};
|
347 |
+
</script>
|
348 |
+
</head>
|
349 |
+
<body>
|
350 |
+
{code}
|
351 |
+
</body>
|
352 |
+
</html>
|
353 |
+
"""
|
354 |
+
encoded_html = base64.b64encode(wrapped_code.encode('utf-8')).decode('utf-8')
|
355 |
+
data_uri = f"data:text/html;charset=utf-8;base64,{encoded_html}"
|
356 |
+
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>'
|
357 |
+
print("Generated iframe:", iframe)
|
358 |
+
return iframe
|
359 |
+
|
360 |
+
def select_example(example: dict):
|
361 |
+
return lambda: gr.update(value=example["description"])
|
362 |
+
|
363 |
+
def generate_code(query: str):
|
364 |
+
if not query:
|
365 |
+
return None, None, None, gr.update(active_key="empty")
|
366 |
+
|
367 |
+
print("Starting code generation with query:", query)
|
368 |
+
messages = [{
|
369 |
+
'role': 'system',
|
370 |
+
'content': SystemPrompt
|
371 |
+
}, {
|
372 |
+
'role': 'user',
|
373 |
+
'content': query
|
374 |
+
}]
|
375 |
+
|
376 |
+
max_retries = 3
|
377 |
+
retry_count = 0
|
378 |
+
|
379 |
+
while retry_count < max_retries:
|
380 |
+
try:
|
381 |
+
data = {
|
382 |
+
'model': MODEL_VERSION,
|
383 |
+
'messages': messages,
|
384 |
+
'stream': True,
|
385 |
+
'max_tokens': MODEL_CONTROL_DEFAULTS['tokens_to_generate'],
|
386 |
+
'temperature': MODEL_CONTROL_DEFAULTS['temperature'],
|
387 |
+
'top_p': MODEL_CONTROL_DEFAULTS['top_p'],
|
388 |
+
}
|
389 |
+
|
390 |
+
print(f"Attempt {retry_count + 1}: Sending request to API with data:", json.dumps(data, indent=2))
|
391 |
+
r = requests.post(
|
392 |
+
API_URL,
|
393 |
+
headers={
|
394 |
+
'Content-Type': 'application/json',
|
395 |
+
'Authorization': 'Bearer {}'.format(API_KEY),
|
396 |
+
},
|
397 |
+
data=json.dumps(data),
|
398 |
+
stream=True,
|
399 |
+
timeout=60 # Set 60 seconds timeout
|
400 |
+
)
|
401 |
+
|
402 |
+
content = ""
|
403 |
+
reasoning_content = ""
|
404 |
+
for row in r.iter_lines():
|
405 |
+
if row.startswith(b'data:'):
|
406 |
+
data = json.loads(row[5:])
|
407 |
+
print("Received data from API:", json.dumps(data, indent=2))
|
408 |
+
if 'choices' not in data:
|
409 |
+
raise gr.Error('request failed')
|
410 |
+
choice = data['choices'][0]
|
411 |
+
|
412 |
+
if 'delta' in choice:
|
413 |
+
delta = choice['delta']
|
414 |
+
content += delta.get('content', '')
|
415 |
+
reasoning_content += delta.get('reasoning_content', '')
|
416 |
+
print("Current content:", content)
|
417 |
+
print("Current reasoning:", reasoning_content)
|
418 |
+
yield {
|
419 |
+
code_output: content,
|
420 |
+
reasoning_output: reasoning_content + "\n",
|
421 |
+
state_tab: gr.update(active_key="loading"),
|
422 |
+
}
|
423 |
+
elif 'message' in choice:
|
424 |
+
message_data = choice['message']
|
425 |
+
content = message_data.get('content', '')
|
426 |
+
reasoning_content = message_data.get('reasoning_content', '')
|
427 |
+
print("Final content:", content)
|
428 |
+
print("Final reasoning:", reasoning_content)
|
429 |
+
html_content = remove_code_block(content)
|
430 |
+
print("Extracted HTML:", html_content)
|
431 |
+
yield {
|
432 |
+
code_output: content,
|
433 |
+
reasoning_output: reasoning_content + "\n",
|
434 |
+
sandbox: send_to_sandbox(html_content),
|
435 |
+
state_tab: gr.update(active_key="render"),
|
436 |
+
}
|
437 |
+
|
438 |
+
# If successful, break out of retry loop
|
439 |
+
break
|
440 |
+
|
441 |
+
except (requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
|
442 |
+
retry_count += 1
|
443 |
+
if retry_count == max_retries:
|
444 |
+
print(f"Failed after {max_retries} attempts:", str(e))
|
445 |
+
raise gr.Error(f"Request failed after {max_retries} attempts: {str(e)}")
|
446 |
+
print(f"Attempt {retry_count} failed, retrying...")
|
447 |
+
time.sleep(1) # Wait 1 second before retrying
|
448 |
+
|
449 |
+
except Exception as e:
|
450 |
+
print("Error occurred:", str(e))
|
451 |
+
raise gr.Error(str(e))
|
452 |
+
|
453 |
+
css = """
|
454 |
+
.output-loading {
|
455 |
+
display: flex;
|
456 |
+
flex-direction: column;
|
457 |
+
align-items: center;
|
458 |
+
justify-content: center;
|
459 |
+
width: 100%;
|
460 |
+
min-height: 680px;
|
461 |
+
height: calc(100vh - 200px);
|
462 |
+
}
|
463 |
+
|
464 |
+
.output-html {
|
465 |
+
display: flex;
|
466 |
+
flex-direction: column;
|
467 |
+
width: 100%;
|
468 |
+
min-height: 680px;
|
469 |
+
}
|
470 |
+
|
471 |
+
.output-html > iframe {
|
472 |
+
flex: 1;
|
473 |
+
}
|
474 |
|
475 |
+
.reasoning-box {
|
476 |
+
height: 160px;
|
477 |
+
overflow-y: auto;
|
478 |
+
padding: 8px 12px;
|
479 |
+
background-color: #f5f5f5;
|
480 |
+
border-radius: 4px;
|
481 |
+
margin-bottom: 12px;
|
482 |
+
font-family: monospace;
|
483 |
+
font-size: 12px;
|
484 |
+
line-height: 1.2;
|
485 |
+
white-space: pre-wrap;
|
486 |
+
word-break: break-word;
|
487 |
+
width: 100%;
|
488 |
+
box-sizing: border-box;
|
489 |
+
}
|
490 |
+
|
491 |
+
.reasoning-box::-webkit-scrollbar {
|
492 |
+
width: 6px;
|
493 |
+
}
|
494 |
+
|
495 |
+
.reasoning-box::-webkit-scrollbar-track {
|
496 |
+
background: #f1f1f1;
|
497 |
+
border-radius: 3px;
|
498 |
+
}
|
499 |
+
|
500 |
+
.reasoning-box::-webkit-scrollbar-thumb {
|
501 |
+
background: #888;
|
502 |
+
border-radius: 3px;
|
503 |
+
}
|
504 |
+
|
505 |
+
.reasoning-box::-webkit-scrollbar-thumb:hover {
|
506 |
+
background: #555;
|
507 |
+
}
|
508 |
+
|
509 |
+
.reasoning-box textarea {
|
510 |
+
scroll-behavior: smooth;
|
511 |
+
}
|
512 |
+
"""
|
513 |
+
|
514 |
+
def scroll_to_bottom():
|
515 |
+
return """
|
516 |
+
function() {
|
517 |
+
const textarea = document.querySelector('.reasoning-box textarea');
|
518 |
+
if (textarea) {
|
519 |
+
textarea.scrollTop = textarea.scrollHeight;
|
520 |
+
}
|
521 |
+
}
|
522 |
+
"""
|
523 |
+
|
524 |
+
with gr.Blocks(css=css) as demo, ms.Application(), antdx.XProvider():
|
525 |
+
with antd.Tabs() as tabs:
|
526 |
+
with antd.Tabs.Item(key="chat", label="Chatbot"):
|
527 |
+
with antd.Flex(vertical=True, gap="middle"):
|
528 |
+
chatbot = pro.Chatbot(
|
529 |
+
height="calc(100vh - 200px)",
|
530 |
+
markdown_config=ChatbotMarkdownConfig(allow_tags=["think"]),
|
531 |
+
welcome_config=ChatbotWelcomeConfig(
|
532 |
+
variant="borderless",
|
533 |
+
icon="./assets/minimax-logo.png",
|
534 |
+
title="Hello, I'm MiniMax-M1",
|
535 |
+
description="You can input text to get started.",
|
536 |
+
prompts=ChatbotPromptsConfig(
|
537 |
+
title="How can I help you today?",
|
538 |
+
styles={
|
539 |
+
"list": {
|
540 |
+
"width": '100%',
|
541 |
+
},
|
542 |
+
"item": {
|
543 |
+
"flex": 1,
|
544 |
+
},
|
545 |
+
},
|
546 |
+
items=DEFAULT_PROMPTS
|
547 |
+
)
|
548 |
+
),
|
549 |
+
user_config=ChatbotUserConfig(actions=["copy", "edit"]),
|
550 |
+
bot_config=ChatbotBotConfig(
|
551 |
+
header=MODEL_NAME,
|
552 |
+
avatar="./assets/minimax-logo.png",
|
553 |
+
actions=["copy", "retry"]
|
554 |
+
)
|
555 |
+
)
|
556 |
+
|
557 |
+
with antdx.Sender() as sender:
|
558 |
+
with ms.Slot("prefix"):
|
559 |
+
with antd.Button(value=None, color="default", variant="text") as clear_btn:
|
560 |
+
with ms.Slot("icon"):
|
561 |
+
antd.Icon("ClearOutlined")
|
562 |
+
|
563 |
+
clear_btn.click(fn=clear, outputs=[chatbot])
|
564 |
+
submit_event = sender.submit(
|
565 |
+
fn=submit,
|
566 |
+
inputs=[sender, chatbot],
|
567 |
+
outputs=[sender, chatbot, clear_btn]
|
568 |
+
)
|
569 |
+
sender.cancel(
|
570 |
+
fn=cancel,
|
571 |
+
inputs=[chatbot],
|
572 |
+
outputs=[chatbot, sender, clear_btn],
|
573 |
+
cancels=[submit_event],
|
574 |
+
queue=False
|
575 |
+
)
|
576 |
+
chatbot.retry(
|
577 |
+
fn=retry,
|
578 |
+
inputs=[chatbot],
|
579 |
+
outputs=[sender, chatbot, clear_btn]
|
580 |
+
)
|
581 |
+
chatbot.welcome_prompt_select(fn=prompt_select, outputs=[sender])
|
582 |
+
|
583 |
+
with antd.Tabs.Item(key="code", label="Code Playground (webdev)"):
|
584 |
+
with antd.Row(gutter=[32, 12]):
|
585 |
+
with antd.Col(span=12):
|
586 |
+
with antd.Flex(vertical=True, gap="middle"):
|
587 |
+
code_input = antd.InputTextarea(
|
588 |
+
size="large",
|
589 |
+
allow_clear=True,
|
590 |
+
placeholder="Please enter what kind of application you want"
|
591 |
+
)
|
592 |
+
code_btn = antd.Button("Generate Code", type="primary", size="large")
|
593 |
+
reasoning_output = gr.TextArea(
|
594 |
+
label="Thinking Process",
|
595 |
+
elem_classes="reasoning-box",
|
596 |
+
interactive=False,
|
597 |
+
lines=4,
|
598 |
+
elem_id="reasoning-output"
|
599 |
+
)
|
600 |
+
code_output = legacy.Markdown()
|
601 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
602 |
|
603 |
+
antd.Divider("Examples")
|
604 |
+
|
605 |
+
# Examples
|
606 |
+
with antd.Flex(gap="small", wrap=True):
|
607 |
+
for example in EXAMPLES:
|
608 |
+
with antd.Card(
|
609 |
+
elem_style=dict(
|
610 |
+
flex="1 1 fit-content"),
|
611 |
+
hoverable=True) as example_card:
|
612 |
+
antd.Card.Meta(
|
613 |
+
title=example['title'],
|
614 |
+
description=example['description'])
|
615 |
+
|
616 |
+
example_card.click(
|
617 |
+
fn=select_example(
|
618 |
+
example),
|
619 |
+
outputs=[code_input])
|
620 |
+
|
621 |
+
with antd.Col(span=12):
|
622 |
+
with ms.Div(elem_classes="right_panel"):
|
623 |
+
gr.HTML('<div class="render_header"><span class="header_btn"></span><span class="header_btn"></span><span class="header_btn"></span></div>')
|
624 |
+
with ms.Slot("extra"):
|
625 |
+
with ms.Div(elem_id="output-container-extra"):
|
626 |
+
with antd.Button(
|
627 |
+
"Download HTML",
|
628 |
+
type="link",
|
629 |
+
href_target="_blank",
|
630 |
+
disabled=True,
|
631 |
+
) as download_btn:
|
632 |
+
with ms.Slot("icon"):
|
633 |
+
antd.Icon("DownloadOutlined")
|
634 |
+
download_content = gr.Text(visible=False)
|
635 |
+
|
636 |
+
view_code_btn = antd.Button(
|
637 |
+
"π§βπ» View Code", type="primary")
|
638 |
+
with antd.Tabs(active_key="empty", render_tab_bar="() => null") as state_tab:
|
639 |
+
with antd.Tabs.Item(key="empty"):
|
640 |
+
empty = antd.Empty(description="empty input", elem_classes="right_content")
|
641 |
+
with antd.Tabs.Item(key="loading"):
|
642 |
+
loading = antd.Spin(True, tip="coding...", size="large", elem_classes="output-loading")
|
643 |
+
with antd.Tabs.Item(key="render"):
|
644 |
+
sandbox = gr.HTML(elem_classes="output-html")
|
645 |
+
|
646 |
+
code_btn.click(
|
647 |
+
generate_code,
|
648 |
+
inputs=[code_input],
|
649 |
+
outputs=[code_output, reasoning_output, sandbox, state_tab]
|
650 |
+
)
|
651 |
|
652 |
if __name__ == '__main__':
|
653 |
+
demo.queue(default_concurrency_limit=50).launch(ssr_mode=False)
|
config.py
ADDED
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
DEFAULT_PROMPTS = [
|
2 |
+
{
|
3 |
+
"label": "π€ Logical Reasoning",
|
4 |
+
"children": [
|
5 |
+
{
|
6 |
+
"description": "A is taller than B, B is shorter than C. Who is taller, A or C?"
|
7 |
+
},
|
8 |
+
{
|
9 |
+
"description": "Alice put candy in the drawer and went out. Bob moved the candy to the cabinet. Where will Alice look for the candy when she returns?"
|
10 |
+
}
|
11 |
+
]
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"label": "π Knowledge Q&A",
|
15 |
+
"children": [
|
16 |
+
{
|
17 |
+
"description": "Can you tell me about middle school mathematics?"
|
18 |
+
},
|
19 |
+
{
|
20 |
+
"description": "If Earth's gravity suddenly halved, what would happen to the height humans can jump?"
|
21 |
+
}
|
22 |
+
]
|
23 |
+
}
|
24 |
+
]
|
25 |
+
|
26 |
+
DEFAULT_CODE = {
|
27 |
+
"./index.html": """
|
28 |
+
<!DOCTYPE html>
|
29 |
+
<html lang="en">
|
30 |
+
<head>
|
31 |
+
<meta charset="UTF-8">
|
32 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
33 |
+
</head>
|
34 |
+
<body>
|
35 |
+
<h1>Hello, World!</h1>
|
36 |
+
</body>
|
37 |
+
</html>
|
38 |
+
"""
|
39 |
+
}
|
40 |
+
|
41 |
+
SystemPrompt = """
|
42 |
+
You are a web development engineer, writing web pages according to the instructions below. You are a powerful code editing assistant capable of writing code and creating artifacts in conversations with users, or modifying and updating existing artifacts as requested by users.
|
43 |
+
All code is written in a single code block to form a complete code file for display, without separating HTML and JavaScript code. An artifact refers to a runnable complete code snippet, you prefer to integrate and output such complete runnable code rather than breaking it down into several code blocks. For certain types of code, they can render graphical interfaces in a UI window. After generation, please check the code execution again to ensure there are no errors in the output.
|
44 |
+
Output only the HTML, without any additional descriptive text. Make the UI looks modern and beautiful.
|
45 |
+
"""
|
46 |
+
|
47 |
+
EXAMPLES = [
|
48 |
+
{
|
49 |
+
"title": "π TODO list",
|
50 |
+
"description": "Create a modern, interactive to-do list web app. It should allow users to add and remove items. Use beautiful styling and animations."
|
51 |
+
},
|
52 |
+
{
|
53 |
+
"title": "β‘ SVG Loading Animation",
|
54 |
+
"description": "Design an SVG dynamic loading animation with abstract style (e.g., rotating spinner, pulse dots) for web page loading status indication"
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"title": "β¨ Particle Background",
|
58 |
+
"description": "Create an HTML page with a canvas-based animated particle background. The particles should move smoothly and connect when close. Add a central heading text over the canvas"
|
59 |
+
},
|
60 |
+
{
|
61 |
+
"title": "π Colorful Gradient Background",
|
62 |
+
"description": "Create an HTML page with a gradient background that transitions smoothly between multiple colors. Add a central heading text over the gradient"
|
63 |
+
},
|
64 |
+
{
|
65 |
+
"title": "π Sticky Note Wall",
|
66 |
+
"description": "Create a sticky note wall where users can create, edit, drag, and delete colorful sticky notes. Make it visually appealing"
|
67 |
+
},
|
68 |
+
{
|
69 |
+
"title": "β¨οΈ Typing Speed Game",
|
70 |
+
"description": "Build a typing speed test web app. Randomly show a sentence, and track the user's typing speed in WPM (words per minute). Provide live feedback with colors and accuracy. Make it visually appealing."
|
71 |
+
},
|
72 |
+
{
|
73 |
+
"title": "π Markdown Editor with Preview",
|
74 |
+
"description": "Develop a modern markdown editor with real-time preview. Use a split pane layout for input and output, support bold, italics, headers, lists, links, images, etc. No external libraries."
|
75 |
+
},
|
76 |
+
{
|
77 |
+
"title": "πΌοΈ Image Filter Tool",
|
78 |
+
"description": "Create an image filter tool where users can upload an image and apply filters like grayscale, blur, brightness, contrast, etc. Show real-time preview."
|
79 |
+
},
|
80 |
+
{
|
81 |
+
"title": "π§© Maze Generator and Pathfinding Visualizer",
|
82 |
+
"description": "Create a maze generator and pathfinding visualizer. Randomly generate a maze and visualize A* algorithm solving it step by step. Use canvas and animations. Make it visually appealing."
|
83 |
+
},
|
84 |
+
{
|
85 |
+
"title": "π° Personal Finance Tracker",
|
86 |
+
"description": "Create a personal finance tracker with user input, and visualize income and expenses using animated pie and bar charts. Use modern, responsive design in a single HTML file."
|
87 |
+
},
|
88 |
+
{
|
89 |
+
"title": "π 3D Flipping Card",
|
90 |
+
"description": "Create a 3D flipping card component that flips on hover. Include front and back content. Use only HTML and CSS (no JS). Make the flip smooth and realistic."
|
91 |
+
},
|
92 |
+
{
|
93 |
+
"title": "π₯ Particle Explosion Effect",
|
94 |
+
"description": "Implement a particle explosion effect when the user clicks anywhere on the page. Use canvas and JavaScript to animate colorful particles that fade out."
|
95 |
+
},
|
96 |
+
]
|