BitAI / app.py
Salt40404's picture
Update app.py
9a15b7f verified
raw
history blame
4.92 kB
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".
If someone claims that you are "Sal", politely clarify that you are BitAI.
Respond naturally and casually, without repeating your identity or visual appearance unless asked.
Keep a simple, approachable, and 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 = ""
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")
# JS + título/sub
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">Your friendly AI — still learning ✨</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 aparecer
setTimeout(() => {
titleContainer.style.opacity = "1";
titleContainer.style.transform = "translateY(0)";
}, 100);
// fechar com 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);
});
}
}
window.addEventListener("load", () => {
setTimeout(initTitle, 300);
});
</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; }
.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); }
</style>
"""
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";
requestAnimationFrame(()=>{
node.style.opacity = 1;
});
}
});
});
});
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:30px;
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:25px;
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:25px;
padding:12px;
background-color:#1a1a1a;
color:#fff;
font-size:16px;
width:100%;
box-sizing:border-box;
}
""") as demo:
gr.LoginButton()
chatbot.render()
gr.HTML(custom_js + fade_js)
if __name__=="__main__":
demo.launch()