import gradio as gr from huggingface_hub import InferenceClient import os HF_TOKEN = os.getenv("HF_TOKEN") # Allowed subjects keywords + common Chemistry, Physics, Maths, Biology terms ALLOWED_KEYWORDS = [ "biology", "physics", "chemistry", "math", "mathematics", "acid", "base", "neutralization", "molecule", "atom", "cell", "force", "energy", "gravity", "equation", "algebra", "calculus", "integral", "derivative" ] def respond(message, history: list[dict[str, str]]): # Check if message contains allowed topics/keywords if not any(keyword in message.lower() for keyword in ALLOWED_KEYWORDS): yield "❌ Sorry, I only know about Biology, Physics, Chemistry, and Maths. Please ask me about them." return # Allowed topic → send to GPT model client = InferenceClient(token=HF_TOKEN, model="openai/gpt-oss-20b") messages = [ {"role": "system", "content": "You are a friendly chatbot. You only answer questions about Biology, Physics, Chemistry, and Maths. For anything else, politely reply that you can't answer it."} ] messages.extend(history) messages.append({"role": "user", "content": message}) response = "" for msg in client.chat_completion( messages, max_tokens=512, stream=True, temperature=0.7, top_p=0.95 ): if msg.choices and msg.choices[0].delta.content: response += msg.choices[0].delta.content yield response # 💜 Modern CSS + Footer Hide + Compact Layout custom_css = """ .gradio-container { background: linear-gradient(to bottom right, #7E498B, #f5f5f5); font-family: 'Segoe UI', sans-serif; height: 100vh; padding: 20px; } /* Chat box styling */ .svelte-1ipelgc, .svelte-1f354aw { border-radius: 20px !important; background: white !important; padding: 12px !important; box-shadow: 0px 6px 25px rgba(0,0,0,0.12) !important; max-width: 700px !important; margin: 0 auto !important; } /* User bubble */ .user.svelte-1ipelgc { background: linear-gradient(135deg, #7E498B, #9b59b6) !important; color: white !important; border-radius: 20px 20px 0 20px !important; padding: 12px 16px !important; max-width: 80% !important; animation: fadeIn 0.3s ease-in; } /* Bot bubble */ .bot.svelte-1ipelgc { background: #f1f1f1 !important; color: #333 !important; border-radius: 20px 20px 20px 0 !important; padding: 12px 16px !important; max-width: 80% !important; box-shadow: 0px 2px 8px rgba(0,0,0,0.05) !important; animation: fadeIn 0.3s ease-in; } /* Input box */ textarea { border-radius: 30px !important; padding: 14px 18px !important; border: 1px solid #ddd !important; outline: none !important; font-size: 16px !important; resize: none !important; } /* Send button */ button { border-radius: 30px !important; background: linear-gradient(135deg, #7E498B, #9b59b6) !important; color: white !important; font-weight: bold !important; transition: 0.3s; } button:hover { background: #632f73 !important; } /* Animations */ @keyframes fadeIn { from {opacity: 0; transform: translateY(10px);} to {opacity: 1; transform: translateY(0);} } /* 🔒 Hide Gradio Footer */ footer, .svelte-1yycg3h, .builder-bar, .wrap.svelte-1ipelgc { display: none !important; visibility: hidden !important; } """ with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo: gr.ChatInterface(respond, type="messages") if __name__ == "__main__": demo.launch(share=True)