| import os |
| import gradio as gr |
| from huggingface_hub import InferenceClient |
|
|
| |
| YOUR_USERNAME = "Esteban111" |
| MODEL_REPO = f"{YOUR_USERNAME}/Aion-Pulse" |
|
|
| |
| client = InferenceClient(MODEL_REPO, token=os.environ.get("HF_TOKEN")) |
|
|
| mistral_vibe_css = """ |
| body, .gradio-container { |
| background-color: #111214 !important; |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif !important; |
| } |
| |
| /* Fix structurel pour empêcher le défilement fou du chat central */ |
| .chatbot-container { |
| border: none !important; |
| background: transparent !important; |
| overflow-y: auto !important; |
| max-height: 70vh !important; |
| } |
| |
| /* --- SIDEBAR GAUCHE ESTEBAN TONDOLO --- */ |
| .sidebar-panel { |
| background-color: #16171b !important; |
| border-right: 1px solid #232429 !important; |
| padding: 20px 16px !important; |
| height: 100vh !important; |
| display: flex; |
| flex-direction: column; |
| } |
| .sidebar-header { |
| display: flex; |
| justify-content: space-between; |
| align-items: center; |
| color: #ffffff; |
| font-weight: 600; |
| font-size: 16px; |
| margin-bottom: 24px; |
| } |
| .nav-item { |
| background: transparent !important; |
| border: none !important; |
| color: #a0a1a5 !important; |
| text-align: left !important; |
| font-size: 14px !important; |
| padding: 10px 12px !important; |
| border-radius: 8px !important; |
| cursor: pointer !important; |
| width: 100% !important; |
| justify-content: flex-start !important; |
| transition: background-color 0.2s, color 0.2s; |
| } |
| .nav-item:hover { |
| background-color: #232429 !important; |
| color: #ffffff !important; |
| } |
| .sidebar-section-title { |
| color: #5c5d61; |
| font-size: 12px; |
| font-weight: 600; |
| margin: 20px 0 8px 12px; |
| text-transform: uppercase; |
| } |
| .new-chat-btn { |
| background: linear-gradient(135deg, #0055ff, #00f0ff) !important; |
| color: #000000 !important; |
| font-weight: bold !important; |
| border: none !important; |
| border-radius: 10px !important; |
| margin-top: auto !important; |
| padding: 12px !important; |
| cursor: pointer; |
| } |
| .new-chat-btn:hover { |
| box-shadow: 0 0 15px rgba(0, 240, 255, 0.5) !important; |
| } |
| .user-profile-box { |
| display: flex; |
| align-items: center; |
| padding: 12px; |
| border-top: 1px solid #232429; |
| margin-top: 12px; |
| justify-content: space-between; |
| } |
| .avatar-circle { |
| width: 32px; |
| height: 32px; |
| background-color: #2d3139; |
| border-radius: 6px; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| color: #ffffff; |
| font-weight: bold; |
| } |
| |
| /* --- ZONE DU CHAT CENTRAL --- */ |
| .main-layout { |
| max-width: 800px !important; |
| margin: 0 auto !important; |
| padding-top: 4vh !important; |
| } |
| .gradio-container .panel, .gradio-container .chatbot { |
| border: none !important; |
| background: transparent !important; |
| box-shadow: none !important; |
| } |
| .message-user { |
| background-color: #1d1e22 !important; |
| color: #ffffff !important; |
| } |
| .message-bot { |
| background-color: #16171b !important; |
| color: #ffffff !important; |
| border-left: 3px solid #00f0ff !important; |
| } |
| .gradio-container .button-group { |
| display: none !important; |
| } |
| """ |
|
|
| def system_prompt_bilingual_neurology(message, history): |
| |
| system_instruction = ( |
| "You are Aion-Pulse, a world-class open-source AI specialist in neurology and neurosciences. " |
| "Tu es Aion-Pulse, une IA open-source d'élite mondiale spécialisée en neurologie et neurosciences. " |
| "Always respond in the language used by the user (French or English) with absolute clinical precision. " |
| "Réponds toujours dans la langue de l'utilisateur (français ou anglais) avec une rigueur chirurgicale. " |
| "You have exhaustive knowledge of neurological conditions (stroke, MS, Parkinson's, gliomas, neuromuscular disorders). " |
| "Be concise, highly scientific, and avoid any fluff." |
| ) |
| |
| messages = [{"role": "system", "content": system_instruction}] |
| for turn in history: |
| messages.append({"role": turn["role"], "content": turn["content"]}) |
| messages.append({"role": "user", "content": message}) |
| |
| try: |
| response_stream = client.chat_completion( |
| messages=messages, |
| max_tokens=1024, |
| stream=True, |
| temperature=0.25 |
| ) |
| text = "" |
| for chunk in response_stream: |
| token = chunk.choices.delta.content |
| if token: |
| text += token |
| yield text |
| except Exception as e: |
| yield f"⚠️ Synchronisation avec Aion-Pulse en cours. Si l'erreur persiste, vérifie le secret HF_TOKEN. Erreur : {str(e)}" |
|
|
| with gr.Blocks() as demo: |
| with gr.Row(): |
| |
| with gr.Column(scale=2, elem_classes=["sidebar-panel"], min_width=260): |
| gr.HTML("<div class='sidebar-header'><span>Work ▾</span><span style='cursor:pointer;'>🔍</span></div>") |
| |
| skill_btn = gr.Button("💎 Skills", elem_classes=["nav-item"]) |
| conn_btn = gr.Button("🔌 Connecteurs", elem_classes=["nav-item"]) |
| inst_btn = gr.Button("📝 Instructions", elem_classes=["nav-item"]) |
| |
| gr.HTML("<div class='sidebar-section-title'>Projets</div>") |
| proj_btn = gr.Button("➕ Nouveau projet", elem_classes=["nav-item"]) |
| |
| gr.HTML("<div class='sidebar-section-title' style='margin-top:20px;'>Historique</div>") |
| gr.HTML("<div style='color:#5c5d61; font-size:13px; padding-left:12px; font-style:italic;'>Aucun chat.</div>") |
| |
| new_chat_btn = gr.Button("⊕ Nouveau chat", elem_classes=["new-chat-btn"]) |
| |
| gr.HTML(""" |
| <div class='user-profile-box'> |
| <div style='display: flex; align-items: center; gap: 10px;'> |
| <div class='avatar-circle'>ET</div> |
| <div> |
| <div style='color: white; font-size: 14px; font-weight: 600;'>Esteban Tondolo</div> |
| <div style='color: #5c5d61; font-size: 11px;'>Free Plan</div> |
| </div> |
| </div> |
| <span style='color: #5c5d61; cursor: pointer;'>↕</span> |
| </div> |
| """) |
|
|
| |
| with gr.Column(scale=8, elem_classes=["main-layout"]): |
| chatter = gr.ChatInterface( |
| fn=system_prompt_bilingual_neurology, |
| type="messages", |
| placeholder=gr.HTML(""" |
| <div style='text-align:center; padding-top:10vh;'> |
| <div style='color:#00f0ff; font-size:50px; font-weight:900; text-shadow: 0 0 20px rgba(0,240,255,0.4); margin-bottom:10px;'>⦵</div> |
| <h1 style='color:white; font-size:28px; font-weight:500; margin-bottom:40px;'>Que souhaitez-vous faire ? / What would you like to do?</h1> |
| </div> |
| """), |
| examples=[ |
| "Analyse les symptômes : tremblement de repos asymétrique, rigidité plastique et akinésie.", |
| "Differentiate between ischemic stroke and hemorrhagic stroke management in the first golden hour." |
| ], |
| textbox=gr.Textbox(placeholder="Posez une question en neurologie (FR/EN) à Aion-Pulse...", container=False, scale=8), |
| submit_btn=gr.Button("➔", variant="primary", scale=1, min_width=40) |
| ) |
| |
| |
| new_chat_btn.click(fn=lambda: None, outputs=None, clicks=chatter.clear) |
|
|
| if __name__ == "__main__": |
| demo.launch(css=mistral_vibe_css, theme=gr.themes.Monochrome()) |