Chaty / app.py
scottlily6's picture
Update app.py
09f0b59 verified
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"}]
)