Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import time | |
| # ===================================================== | |
| # THEME | |
| # ===================================================== | |
| theme = gr.themes.Soft( | |
| primary_hue="cyan", | |
| secondary_hue="blue", | |
| neutral_hue="slate", | |
| font=gr.themes.GoogleFont("Inter"), | |
| ).set( | |
| body_background_fill="*neutral_950", | |
| block_background_fill="*neutral_900", | |
| block_border_color="*neutral_800", | |
| body_text_color="*neutral_100", | |
| button_primary_background_fill="*primary_600", | |
| button_primary_background_fill_hover="*primary_500", | |
| ) | |
| # ===================================================== | |
| # CSS GLOBAL (DARK + ANIMATIONS) | |
| # ===================================================== | |
| css = """ | |
| body { | |
| background-color: #121212; | |
| color: #e0e0e0; | |
| } | |
| [data-testid="chatbot-message"] { | |
| animation: fadeIn 0.3s ease-out; | |
| } | |
| @keyframes fadeIn { | |
| from { opacity: 0; transform: translateY(10px); } | |
| to { opacity: 1; transform: translateY(0); } | |
| } | |
| button.primary-btn:hover { | |
| animation: pulse 0.5s infinite; | |
| box-shadow: 0 0 15px rgba(21,101,192,0.6); | |
| } | |
| @keyframes pulse { | |
| 0%,100%{transform:scale(1);} | |
| 50%{transform:scale(1.05);} | |
| } | |
| .sidebar-glass { | |
| background: rgba(18,18,18,0.95); | |
| backdrop-filter: blur(10px); | |
| } | |
| [data-testid="chatbot"]::-webkit-scrollbar { | |
| width: 6px; | |
| } | |
| [data-testid="chatbot"]::-webkit-scrollbar-thumb { | |
| background: #474747; | |
| border-radius: 10px; | |
| } | |
| """ | |
| # ===================================================== | |
| # IA (SIMULÉE STREAMING) | |
| # ===================================================== | |
| def generate_response(msg, system_prompt, temperature, max_tokens): | |
| """ | |
| Generates a simulated AI response with a streaming effect. | |
| Args: | |
| msg: The user's message. | |
| system_prompt: The system prompt configuration. | |
| temperature: The temperature setting. | |
| max_tokens: The maximum token limit. | |
| Yields: | |
| Partial response strings for streaming display. | |
| """ | |
| time.sleep(0.3) | |
| response = f"""Message reçu : **{msg}** | |
| System prompt : `{system_prompt}` | |
| Température : `{temperature}` | |
| Réponse IA simulée en streaming. | |
| """ | |
| # Simulate truncation based on max_tokens | |
| response = response[: max_tokens * 4] | |
| partial = "" | |
| for w in response.split(): | |
| partial += w + " " | |
| yield partial | |
| time.sleep(0.04) | |
| # ===================================================== | |
| # APP | |
| # ===================================================== | |
| # Gradio 6 Syntax: NO parameters in gr.Blocks() | |
| with gr.Blocks() as demo: | |
| # ================= NAVBAR ================= | |
| gr.HTML(""" | |
| <style> | |
| .navbar { | |
| background: linear-gradient(90deg,#000,#1e1e1e); | |
| border-bottom:1px solid #333; | |
| color:white; | |
| } | |
| .nav-container { | |
| max-width:1200px; | |
| margin:auto; | |
| display:flex; | |
| justify-content:space-between; | |
| align-items:center; | |
| padding:16px 24px; | |
| } | |
| .nav-links {display:flex;gap:24px;align-items:center;} | |
| .nav-link {color:#e5e7eb;text-decoration:none;} | |
| .nav-link:hover{color:#a5b4fc;} | |
| .hamburger{display:none;cursor:pointer;} | |
| .mobile-menu{max-height:0;overflow:hidden;transition:0.3s;} | |
| .mobile-menu.open{max-height:300px;} | |
| @media(max-width:768px){ | |
| .nav-links{display:none;} | |
| .hamburger{display:block;} | |
| } | |
| </style> | |
| <nav class="navbar"> | |
| <div class="nav-container"> | |
| <strong>🤖 ChatBot Prodigy</strong> | |
| <div class="nav-links"> | |
| <a class="nav-link" href="#">Home</a> | |
| <a class="nav-link" href="#">Features</a> | |
| <a class="nav-link" href="#">Docs</a> | |
| <a class="nav-link" href="#">Deploy</a> | |
| <a class="nav-link" href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a> | |
| </div> | |
| <div class="hamburger" id="hamburger">☰</div> | |
| </div> | |
| <div class="mobile-menu" id="mobileMenu"> | |
| <a class="nav-link" href="#">Home</a><br> | |
| <a class="nav-link" href="#">Features</a><br> | |
| <a class="nav-link" href="#">Docs</a><br> | |
| <a class="nav-link" href="#">Deploy</a><br> | |
| <a class="nav-link" href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">Built with anycoder</a> | |
| </div> | |
| </nav> | |
| <script> | |
| const h=document.getElementById("hamburger"); | |
| const m=document.getElementById("mobileMenu"); | |
| h.onclick=()=>{m.classList.toggle("open");h.textContent=m.classList.contains("open")?"✕":"☰";} | |
| </script> | |
| """) | |
| # ================= SIDEBAR ================= | |
| with gr.Sidebar(open=True, elem_classes="sidebar-glass"): | |
| system_prompt = gr.Textbox( | |
| value="You are a professional AI assistant.", | |
| label="System Prompt", | |
| lines=3 | |
| ) | |
| temperature = gr.Slider(0.1, 2.0, value=0.7, step=0.1, label="Temperature") | |
| max_tokens = gr.Slider(100, 4000, value=1024, step=100, label="Max Tokens") | |
| # ================= CHAT ================= | |
| chatbot = gr.Chatbot( | |
| type="messages", | |
| height=500, | |
| show_copy_button=True | |
| ) | |
| msg = gr.Textbox(placeholder="Écrivez votre message…", show_label=False) | |
| send = gr.Button("Envoyer", variant="primary", elem_classes="primary-btn") | |
| def user_msg(m, h): | |
| """Appends the user message to the chat history.""" | |
| h = h or [] | |
| h.append({"role": "user", "content": m}) | |
| return "", h | |
| def bot_msg(h, sp, t, mt): | |
| """ | |
| Generates and streams the bot response. | |
| Updates the last message (assistant role) in the history. | |
| """ | |
| h.append({"role": "assistant", "content": ""}) | |
| # Get the last user message (h[-2]) to generate context | |
| last_user_msg = h[-2]["content"] if len(h) >= 2 else "" | |
| for chunk in generate_response(last_user_msg, sp, t, mt): | |
| h[-1]["content"] = chunk | |
| yield h | |
| # Event Listeners | |
| msg.submit(user_msg, [msg, chatbot], [msg, chatbot], queue=False)\ | |
| .then(bot_msg, [chatbot, system_prompt, temperature, max_tokens], chatbot) | |
| send.click(user_msg, [msg, chatbot], [msg, chatbot], queue=False)\ | |
| .then(bot_msg, [chatbot, system_prompt, temperature, max_tokens], chatbot) | |
| # ================= FOOTER ================= | |
| gr.HTML(""" | |
| <footer style="background:#000;border-top:1px solid #333;color:#9ca3af;margin-top:40px;"> | |
| <div style="max-width:1200px;margin:auto;padding:32px;display:grid;grid-template-columns:repeat(4,1fr);gap:24px;"> | |
| <div><strong>🤖 ChatBot Prodigy Wizard</strong><p>AI-powered assistant with dark magic.</p></div> | |
| <div><strong>Links</strong><br><a href="#">Home</a><br><a href="#">Features</a></div> | |
| <div><strong>Resources</strong><br><a href="https://gradio.app">Gradio</a><br><a href="https://huggingface.co">HF</a></div> | |
| <div><strong>Connect</strong><br>🐙 🐦 💼 ✉️</div> | |
| </div> | |
| <div style="text-align:center;padding:16px;border-top:1px solid #333;"> | |
| © 2026 ChatBot Prodigy Wizard 🔮 | |
| </div> | |
| </footer> | |
| """) | |
| # ===================================================== | |
| # LAUNCH | |
| # ===================================================== | |
| # Gradio 6: theme, css, and footer_links are parameters of launch() | |
| demo.launch( | |
| theme=theme, | |
| css=css, | |
| footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}] | |
| ) |