| 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 respond politely, refuse inappropriate requests, and keep a friendly tone.""" |
| |
| 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 = chunk.choices[0].delta.content if chunk.choices and chunk.choices[0].delta.content else "" |
| response += token |
| yield response |
|
|
| |
| custom_js = """ |
| <script> |
| function initTitle() { |
| const grContainer = document.querySelector(".gradio-container"); |
| if(grContainer && !document.querySelector(".chat-title")) { |
| const titleContainer = document.createElement("div"); |
| titleContainer.className = "title-container"; |
| titleContainer.innerHTML = ` |
| <div class="title-inner"> |
| <h1 class="chat-title">Talk with BitAI (W.I.P)</h1> |
| <p class="chat-subtitle">Still updating, might not know everything, filter slightly broken</p> |
| <button class="close-title-btn"> |
| <svg width="28" height="28" viewBox="0 0 24 24"> |
| <path fill="#fff" d="M12 16l-6-6h12z"/> |
| </svg> |
| </button> |
| </div> |
| `; |
| grContainer.insertBefore(titleContainer, grContainer.firstChild); |
| |
| // animação de aparecer |
| setTimeout(() => { |
| titleContainer.style.opacity = "1"; |
| titleContainer.style.transform = "translateY(0)"; |
| }, 100); |
| |
| // fechar com a seta |
| const closeBtn = titleContainer.querySelector(".close-title-btn"); |
| closeBtn.addEventListener("click", () => { |
| titleContainer.style.transition = "all 0.4s ease"; |
| titleContainer.style.opacity = "0"; |
| titleContainer.style.transform = "translateY(-20px)"; |
| setTimeout(() => titleContainer.remove(), 400); |
| }); |
| } |
| } |
| |
| // esperar carregar tudo |
| window.addEventListener("load", () => { |
| setTimeout(initTitle, 300); |
| }); |
| |
| // deixar botão de enviar grande |
| window.addEventListener("load", () => { |
| const txtArea = document.querySelector("textarea"); |
| const btn = document.querySelector(".send-btn"); |
| if(txtArea && btn){ |
| const resize = () => { |
| btn.style.height = txtArea.offsetHeight + "px"; |
| btn.style.width = txtArea.offsetHeight + "px"; |
| }; |
| resize(); |
| new ResizeObserver(resize).observe(txtArea); |
| } |
| }); |
| </script> |
| |
| <style> |
| .title-container { |
| text-align:center; |
| margin-bottom:25px; |
| opacity:0; |
| transform:translateY(-20px); |
| transition:0.5s; |
| position:relative; |
| } |
| .title-inner { display:inline-block; position:relative; } |
| .chat-title { font-size:32px; color:#fff; margin-bottom:10px; cursor:pointer; } |
| .chat-subtitle { font-size:14px; color:#aaa; margin-bottom:10px; } |
| .close-title-btn { |
| position:absolute; |
| right:-15px; top:-15px; |
| background:transparent; |
| border:none; |
| cursor:pointer; |
| padding:5px; |
| transition: transform 0.2s; |
| } |
| .close-title-btn:hover { transform:scale(1.2); } |
| .send-btn { |
| border:none; |
| border-radius:50%; |
| background:linear-gradient(145deg,#555,#444); |
| color:#fff; |
| cursor:pointer; |
| transition:0.3s; |
| } |
| </style> |
| """ |
|
|
| |
| with gr.Blocks(css=""" |
| body{background:#000;font-family:'Inter','Manrope','Outfit',sans-serif;} |
| .gradio-container{border-radius:20px;padding:20px;max-width:700px;margin:30px auto; |
| background:linear-gradient(145deg,#0f0f0f,#1a1a1a); |
| box-shadow:0 10px 30px rgba(0,0,0,0.4);} |
| textarea{border:none;border-radius:25px;padding:14px 20px; |
| background:#1a1a1a;color:#fff;font-size:16px;width:100%;min-height:56px;} |
| """) as demo: |
| gr.LoginButton() |
| gr.ChatInterface(respond, type="messages") |
| gr.HTML(custom_js) |
|
|
| if __name__ == "__main__": |
| demo.launch() |