| import gradio as gr |
| from huggingface_hub import InferenceClient |
|
|
| def respond(message, history: list[dict[str, str]], hf_token: gr.OAuthToken): |
| client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b") |
|
|
| system_message = """You are BitAI (or Bit for short), a friendly chatbot created by the user "Sal". |
| You always respond politely and helpfully. If a user requests something appropriate, fulfill it. |
| If a user requests something harmful, illegal, or inappropriate, politely refuse. |
| If a user keeps insisting on harmful requests, firmly tell them to stop and that they cannot use the service for that purpose. |
| Keep a simple, approachable, and friendly tone otherwise.""" |
|
|
| messages = [{"role": "system", "content": system_message}] |
| messages.extend(history) |
| messages.append({"role": "user", "content": message}) |
|
|
| response = "" |
| for chunk in client.chat_completion(messages, max_tokens=512, stream=True, temperature=0.7, top_p=0.95): |
| token = "" |
| if chunk.choices and chunk.choices[0].delta.content: |
| token = chunk.choices[0].delta.content |
| response += token |
| yield response |
|
|
| chatbot = gr.ChatInterface(respond, type="messages") |
|
|
| fade_js = """ |
| <script> |
| const observer = new MutationObserver(mutations=>{ |
| mutations.forEach(m=>{ |
| m.addedNodes.forEach(node=>{ |
| if(node.classList && node.classList.contains('chat-message')){ |
| node.style.opacity = 0; |
| node.style.transition = "opacity 0.4s ease, transform 0.4s ease"; |
| node.style.transform = "translateY(10px)"; |
| requestAnimationFrame(()=>{ |
| node.style.opacity = 1; |
| node.style.transform = "translateY(0)"; |
| }); |
| } |
| }); |
| }); |
| }); |
| |
| document.addEventListener("DOMContentLoaded", ()=>{ |
| const chatContainer = document.querySelector(".chat-interface"); |
| if(chatContainer) observer.observe(chatContainer, {childList:true, subtree:true}); |
| }); |
| </script> |
| """ |
|
|
| with gr.Blocks(css=""" |
| body { |
| background-color:#000; |
| font-family:'Arial',sans-serif; |
| margin:0; |
| padding:0; |
| } |
| .gradio-container { |
| border-radius:45px; |
| padding:20px; |
| max-width:700px; |
| margin:30px auto; |
| background-color:#121212; |
| box-shadow:0 6px 25px rgba(0,0,0,0.3); |
| } |
| .chat-message { |
| border-radius:45px; |
| padding:14px 18px; |
| margin:8px 0; |
| display:flex; |
| flex-direction:column; |
| opacity:0; |
| } |
| .chat-message.user { |
| background-color:#1f1f1f; |
| color:#fff; |
| align-items:flex-end; |
| } |
| .chat-message.bot { |
| background-color:#2b2b2b; |
| color:#fff; |
| align-items:flex-start; |
| } |
| textarea { |
| border:none; |
| outline:none; |
| border-radius:45px; |
| padding:12px; |
| background-color:#1a1a1a; |
| color:#fff; |
| font-size:16px; |
| width:100%; |
| box-sizing:border-box; |
| } |
| .send-btn { |
| border:none; |
| border-radius:45px; |
| background-color:#444; |
| color:#fff; |
| width:48px; |
| height:48px; |
| font-size:18px; |
| display:flex; |
| align-items:center; |
| justify-content:center; |
| cursor:pointer; |
| margin-left:8px; |
| } |
| .send-btn:hover { |
| background-color:#555; |
| } |
| /* login button default Gradio */ |
| .gr-button.gr-login { |
| border-radius:45px !important; |
| background-color:#444 !important; |
| color:#fff !important; |
| margin-bottom:15px; |
| } |
| .gr-button.gr-login:hover { |
| background-color:#555 !important; |
| } |
| """) as demo: |
|
|
| |
| gr.LoginButton() |
| |
| chatbot.render() |
| gr.HTML(fade_js) |
|
|
| if __name__=="__main__": |
| demo.launch() |