Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import time | |
| import random | |
| # --- 1. Configuration du Thème Sombre Pro --- | |
| # Nous utilisons gr.themes.Soft avec des teintes sombres (slate/gray) | |
| custom_theme = gr.themes.Soft( | |
| primary_hue="cyan", # Une touche de cyan pour le côté "Tech/Pro" | |
| secondary_hue="blue", | |
| neutral_hue="slate", # Fond gris foncé/slate | |
| font=gr.themes.GoogleFont("Inter"), # Police moderne et lisible | |
| text_size="lg", | |
| spacing_size="lg", | |
| radius_size="md" | |
| ).set( | |
| # Palette de couleurs sombres personnalisée | |
| body_background_fill="*neutral_950", # Fond presque noir | |
| body_background_fill_dark="*neutral_950", | |
| block_background_fill="*neutral_900", # Fond des blocs légèrement plus clair | |
| block_border_color="*neutral_800", # Bordures subtiles | |
| block_border_width="1px", | |
| # Textes | |
| body_text_color="*neutral_100", # Texte blanc cassé | |
| body_text_color_dark="*neutral_100", | |
| block_title_text_color="*neutral_50", # Titres blancs | |
| block_label_text_color="*neutral_400", # Labels gris clair | |
| # Boutons | |
| button_primary_background_fill="*primary_600", | |
| button_primary_background_fill_hover="*primary_500", | |
| button_primary_text_color="white", | |
| # Input (Chatbox) | |
| input_background_fill="*neutral_950", | |
| input_background_fill_dark="*neutral_950", | |
| border_color_primary="*primary_500", | |
| ) | |
| # --- 2. CSS Personnalisé pour les Animations --- | |
| # Ajoute des effets de fade-in, de glow et de transitions fluides | |
| custom_css = """ | |
| /* Animation d'apparition des messages (Slide Up + Fade) */ | |
| @keyframes slideUpFade { | |
| from { | |
| opacity: 0; | |
| transform: translateY(20px); | |
| } | |
| to { | |
| opacity: 1; | |
| transform: translateY(0); | |
| } | |
| } | |
| /* Animation de pulsation pour le micro */ | |
| @keyframes pulse-glow { | |
| 0% { box-shadow: 0 0 0 0 rgba(6, 182, 212, 0.7); } | |
| 70% { box-shadow: 0 0 0 10px rgba(6, 182, 212, 0); } | |
| 100% { box-shadow: 0 0 0 0 rgba(6, 182, 212, 0); } | |
| } | |
| /* Appliquer l'animation aux bulles de chat */ | |
| .message { | |
| animation: slideUpFade 0.4s ease-out forwards; | |
| } | |
| /* Effet de survol néon sur les boutons */ | |
| button.primary-btn:hover { | |
| box-shadow: 0 0 15px rgba(6, 182, 212, 0.4); | |
| transition: all 0.3s ease; | |
| } | |
| /* Personnalisation de la barre de défilement */ | |
| ::-webkit-scrollbar { | |
| width: 8px; | |
| } | |
| ::-webkit-scrollbar-track { | |
| background: #0f172a; | |
| } | |
| ::-webkit-scrollbar-thumb { | |
| background: #334155; | |
| border-radius: 4px; | |
| } | |
| ::-webkit-scrollbar-thumb:hover { | |
| background: #475569; | |
| } | |
| /* Style spécifique pour le bouton micro en enregistrement */ | |
| .recording-active { | |
| animation: pulse-glow 1.5s infinite; | |
| background-color: #ef4444 !important; | |
| border-color: #ef4444 !important; | |
| color: white !important; | |
| } | |
| /* Glassmorphism léger pour la sidebar */ | |
| .sidebar-glass { | |
| background: rgba(15, 23, 42, 0.95); | |
| backdrop-filter: blur(10px); | |
| } | |
| """ | |
| # --- 3. Logique de l'Application --- | |
| def generate_response(message, history, system_prompt, temperature, max_tokens): | |
| """ | |
| Simule une réponse IA avec effet de streaming (comme dans votre code HTML original). | |
| """ | |
| # Simulation d'un délai de réseau | |
| time.sleep(0.5) | |
| # Génération d'une réponse factice basée sur les paramètres | |
| temp_val = float(temperature) | |
| if "hello" in message.lower() or "bonjour" in message.lower(): | |
| response = f"Bonjour ! Je suis configuré pour être très professionnel. Température actuelle : {temp_val}." | |
| elif "code" in message.lower(): | |
| response = "Voici un exemple de code Python généré :\n\n```python\ndef pro_function():\n return 'Success'\n```" | |
| else: | |
| response = f"J'ai reçu votre message : '{message}'.\n\nPrompt système : '{system_prompt}'.\n\nJe simule ici une réponse IA avec un design sombre et des animations fluides." | |
| # Simulation de l'effet de streaming (mot par mot ou phrase par phrase) | |
| words = response.split(" ") | |
| partial_response = "" | |
| for word in words: | |
| partial_response += word + " " | |
| yield partial_response | |
| time.sleep(0.05) # Vitesse de l'effet de frappe | |
| def transcribe_audio(audio_file): | |
| """ | |
| Simule la transcription audio (Speech-to-Text). | |
| Dans une vraie app, vous utiliseriez `whisper` ou `SpeechRecognition` ici. | |
| """ | |
| if audio_file is None: | |
| return "" | |
| # Simulation : on renvoie un texte fictif pour montrer que ça marche | |
| return "(Ceci est une transcription simulée de l'audio pour la démo)" | |
| # --- 4. Construction de l'Interface Gradio 6 --- | |
| with gr.Blocks(theme=custom_theme, css=custom_css, title="Pro AI Chat") as demo: | |
| # Sidebar pour les réglages (Gradio 6 Feature) | |
| with gr.Sidebar(open=True, elem_classes="sidebar-glass") as sidebar: | |
| gr.Markdown("### ⚙️ Configuration") | |
| gr.Markdown("Paramètres du modèle et de l'interface.") | |
| with gr.Accordion("Paramètres LLM", open=True): | |
| system_prompt = gr.Textbox( | |
| label="System Prompt", | |
| value="You are a helpful, professional AI assistant.", | |
| lines=3, | |
| placeholder="Définissez le comportement de l'IA..." | |
| ) | |
| temperature = gr.Slider( | |
| minimum=0.1, maximum=2.0, step=0.1, value=0.7, | |
| label="Température (Créativité)", | |
| info="Plus c'est haut, plus c'est créatif." | |
| ) | |
| max_tokens = gr.Slider( | |
| minimum=100, maximum=4000, step=100, value=1024, | |
| label="Max Tokens" | |
| ) | |
| with gr.Accordion("Info", open=False): | |
| gr.Markdown(""" | |
| **Instructions:** | |
| 1. Tapez votre message ou utilisez le micro. | |
| 2. Ajustez les paramètres dans la sidebar. | |
| 3. Profitez du mode sombre animé ! | |
| """) | |
| # Zone principale de Chat | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| # Header avec le lien "Built with anycoder" | |
| gr.HTML(""" | |
| <div style="text-align: center; margin-bottom: 10px;"> | |
| <h2 style="margin:0; font-weight:600; color: #e2e8f0;">Pro AI Assistant</h2> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" | |
| style="color: #22d3ee; text-decoration: none; font-size: 0.9em;"> | |
| Built with anycoder ↗ | |
| </a> | |
| </div> | |
| """) | |
| # Chatbot avec historique | |
| chatbot = gr.Chatbot( | |
| label="", | |
| height=500, | |
| show_copy_button=True, | |
| avatar_images=(None, "https://cdn-icons-png.flaticon.com/512/4712/4712009.png"), # Avatar robot optionnel | |
| bubble_full_width=False | |
| ) | |
| with gr.Row(): | |
| # Zone de saisie texte | |
| with gr.Column(scale=4): | |
| msg_input = gr.Textbox( | |
| label="Message", | |
| placeholder="Écrivez votre message ici...", | |
| lines=1, | |
| container=False, | |
| autofocus=True, | |
| show_label=False | |
| ) | |
| # Zone de saisie audio (Microphone) | |
| with gr.Column(scale=1, min_width=80): | |
| audio_input = gr.Audio( | |
| sources=["microphone"], | |
| type="filepath", | |
| label="Microphone", | |
| elem_id="mic-component" | |
| ) | |
| # Bouton d'envoi stylisé | |
| with gr.Column(scale=0, min_width=80): | |
| send_btn = gr.Button("Envoyer", variant="primary", elem_classes="primary-btn", scale=0) | |
| # Exemples | |
| gr.Examples( | |
| examples=[ | |
| ["Bonjour, peux-tu m'écrire du Python ?"], | |
| ["Explique-moi la gravité comme si j'avais 5 ans."], | |
| ["Génère une idée de startup innovante."] | |
| ], | |
| inputs=msg_input | |
| ) | |
| # --- Logique d'interaction --- | |
| def user_message(message, history): | |
| """Ajoute le message de l'utilisateur à l'historique""" | |
| return "", history + [[message, None]] | |
| def bot_response(history, system_prompt, temperature, max_tokens): | |
| """Génère la réponse du bot""" | |
| # Récupérer le dernier message utilisateur | |
| user_msg = history[-1][0] | |
| # Appeler la fonction de génération (streaming) | |
| bot_msg = "" | |
| for chunk in generate_response(user_msg, history, system_prompt, temperature, max_tokens): | |
| bot_msg = chunk | |
| # Mettre à jour l'historique en temps réel | |
| history[-1][1] = bot_msg | |
| yield history | |
| # Gestion des événements | |
| msg_input.submit( | |
| user_message, | |
| [msg_input, chatbot], | |
| [msg_input, chatbot], | |
| queue=False | |
| ).then( | |
| bot_response, | |
| [chatbot, system_prompt, temperature, max_tokens], | |
| chatbot | |
| ) | |
| send_btn.click( | |
| user_message, | |
| [msg_input, chatbot], | |
| [msg_input, chatbot], | |
| queue=False | |
| ).then( | |
| bot_response, | |
| [chatbot, system_prompt, temperature, max_tokens], | |
| chatbot | |
| ) | |
| # Gestion de l'audio (Speech-to-Text simulé) | |
| def process_audio(audio): | |
| if audio: | |
| return transcribe_audio(audio) | |
| return "" | |
| # Quand l'audio est enregistré, on met le texte dans la zone de message | |
| audio_input.stop_recording( | |
| process_audio, | |
| audio_input, | |
| msg_input | |
| ) | |
| # --- 5. Lancement de l'Application --- | |
| # Note: Tous les paramètres globaux (theme, css, footer_links) sont ici | |
| demo.launch( | |
| footer_links=[{"label": "Built with anycoder", "url": "https://huggingface.co/spaces/akhaliq/anycoder"}] | |
| ) |