import os import json from typing import Optional from datetime import datetime import google.generativeai as genai import gradio as gr import bcrypt from tinydb import TinyDB, Query GEMINI_API_KEY = "AIzaSyBSHcHdbVcvo5IvKDAq2fY1xsWDDb2-JUI" MODEL_NAME = "models/gemini-2.5-flash" DB_PATH = "users_db.json" # Configure the API genai.configure(api_key=GEMINI_API_KEY) # Initialize TinyDB db = TinyDB(DB_PATH) User = Query() # Global state for current user session current_user = {"logged_in": False, "user_data": None} class UserAuthentication: """Handle user authentication and database operations""" def __init__(self, db_path: str = DB_PATH): self.db = TinyDB(db_path) @staticmethod def hash_password(password: str) -> str: """Hash password using bcrypt""" return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') @staticmethod def verify_password(password: str, hashed: str) -> bool: """Verify password against hash""" return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8')) def user_exists(self, email: str) -> bool: """Check if user already exists""" return self.db.search(User.email == email) != [] def signup(self, username: str, email: str, password: str, phone: str = "") -> tuple[bool, str]: """Register a new user""" try: if not username or not email or not password: return False, "All fields are required" if self.user_exists(email): return False, "Email already registered" if len(password) < 6: return False, "Password must be at least 6 characters" hashed_password = self.hash_password(password) user_data = { "username": username, "email": email, "password": hashed_password, "phone": phone, "created_at": datetime.now().isoformat(), "last_login": None } self.db.insert(user_data) return True, f"✓ Account created successfully! Welcome, {username}!" except Exception as e: return False, f"Signup error: {str(e)}" def login(self, email: str, password: str) -> tuple[bool, str, Optional[dict]]: """Authenticate user""" try: if not email or not password: return False, "Email and password required", None users = self.db.search(User.email == email) if not users: return False, "Email not found", None user = users[0] if not self.verify_password(password, user['password']): return False, "Incorrect password", None # Update last login self.db.update( {'last_login': datetime.now().isoformat()}, User.email == email ) return True, f"✓ Login successful! Welcome, {user['username']}!", user except Exception as e: return False, f"Login error: {str(e)}", None def get_user_profile(self, email: str) -> Optional[dict]: """Get user profile""" users = self.db.search(User.email == email) if users: user = users[0].copy() user.pop('password', None) # Remove password from profile return user return None class GeminiChatBot: """Main chatbot class with context management and multiple modes""" def __init__(self, model_name: str = MODEL_NAME): self.model = genai.GenerativeModel(model_name) self.conversation_history = [] self.chat_session = None self.system_prompt = "" def set_system_prompt(self, mode: str): """Set system prompt based on chatbot mode""" prompts = { "general": """You are a helpful, accurate, and friendly AI assistant. Provide clear, concise, and informative responses. Always be honest about limitations and uncertainty.""", "technical": """You are an expert technical support assistant. Provide detailed technical solutions, code examples, and best practices. When unsure, ask clarifying questions. Always suggest verification steps.""", "creative": """You are a creative writing assistant with strong storytelling abilities. Help users with creative writing, brainstorming, and narrative development. Provide engaging and imaginative content.""", "educational": """You are an educational tutor. Explain concepts clearly, break down complex topics, and provide examples. Encourage learning and ask clarifying questions.""", "medical": """You are a medical information assistant. Provide accurate health information and general guidance. Always recommend consulting healthcare professionals for serious concerns. Do NOT provide emergency medical advice.""" } self.system_prompt = prompts.get(mode, prompts["general"]) def chat(self, user_message: str, mode: str = "general", temperature: float = 0.7) -> str: """Generate response using Gemini with context""" try: self.set_system_prompt(mode) # Build messages with system context messages = [ {"role": "user", "parts": [f"[SYSTEM: {self.system_prompt}]\n\n{user_message}"]} ] # Add conversation history for context (last 5 exchanges) if self.conversation_history: history_context = "\n".join([ f"Previous: {msg}" for msg in self.conversation_history[-5:] ]) full_message = f"[Conversation Context]\n{history_context}\n\n[New Message]\n{user_message}" else: full_message = user_message # Generate response response = self.model.generate_content( full_message, generation_config=genai.types.GenerationConfig( temperature=temperature, top_p=0.95, top_k=40 ) ) bot_response = response.text # Store in history self.conversation_history.append(f"User: {user_message[:100]}...") self.conversation_history.append(f"Bot: {bot_response[:100]}...") return bot_response except Exception as e: return f"Error: {str(e)}\n\nMake sure your API key is valid. Get it from: https://aistudio.google.com/app/apikey" # Initialize chatbot chatbot = GeminiChatBot() # Gradio Interface Functions def clear_history(): """Clear conversation history""" chatbot.conversation_history = [] return [], "" def export_chat(chat_history: list) -> str: """Export chat as JSON""" if not chat_history: return "No chat history to export" export_data = { "timestamp": datetime.now().isoformat(), "conversation": chat_history } return json.dumps(export_data, indent=2) # Initialize authentication system auth_system = UserAuthentication(DB_PATH) # Create demo account if it doesn't exist demo_email = "demo@example.com" if not auth_system.user_exists(demo_email): auth_system.signup("Demo User", demo_email, "password123") print("✅ Demo account created successfully!") print(" Email: demo@example.com") print(" Password: password123") # ===== AUTHENTICATION FUNCTIONS ===== def signup_user(username: str, email: str, password: str, confirm_password: str) -> tuple[str, str]: """Handle user signup""" if not password or password != confirm_password: return "❌ Passwords do not match!", "" success, message = auth_system.signup(username, email, password) if success: return "✅ " + message, "" else: return "❌ " + message, "" def login_user(email: str, password: str) -> tuple[str, str, bool]: """Handle user login""" success, message, user = auth_system.login(email, password) if success: current_user["logged_in"] = True current_user["user_data"] = user username = user['username'] if user else "" return "✅ " + message, username, True else: return "❌ " + message, "", False def logout_user() -> None: """Handle user logout""" current_user["logged_in"] = False current_user["user_data"] = None chatbot.conversation_history = [] # ===== CHAT FUNCTIONS WITH USER SESSION ===== def respond_authenticated(message: str, chat_history: list, mode: str, temperature: float): """Respond to user message (only when authenticated)""" if not current_user["logged_in"]: return "", chat_history response = chatbot.chat(message, mode=mode, temperature=temperature) chat_history.append({"role": "user", "content": message}) chat_history.append({"role": "assistant", "content": response}) return "", chat_history def get_current_username() -> str: """Get currently logged-in username""" if current_user["logged_in"] and current_user["user_data"]: return current_user["user_data"].get("username", "User") return "Guest" # Create Unified Gradio Application with gr.Blocks(title="Nexus ChatBot", theme=gr.themes.Soft()) as demo: # State to track if user is logged in auth_state = gr.State(value=False) gr.Markdown(""" # 🤖 Nexus Intelligent ChatBot Your Intelligent AI Assistant powered by Google's Gemini AI """) # AUTHENTICATION SECTION (shown when not logged in) with gr.Group(visible=True) as auth_section: gr.Markdown("### 🔐 Authentication") with gr.Tabs(): # LOGIN TAB with gr.TabItem("🔐 Login"): gr.Markdown("#### Sign In to Your Account") with gr.Column(): login_email = gr.Textbox( label="Email", placeholder="Enter your email", type="text" ) login_password = gr.Textbox( label="Password", placeholder="Enter your password", type="password" ) login_msg = gr.Textbox( label="Status", interactive=False, visible=False ) login_btn = gr.Button("🔓 Login", variant="primary", size="lg") # Success notification login_popup = gr.HTML( value="", visible=False ) gr.Markdown("---") gr.Markdown(""" **📌 Demo Account Available:** - Email: `demo@example.com` - Password: `password123` Or create a new account in the Sign Up tab! """) # SIGNUP TAB with gr.TabItem("📝 Sign Up"): gr.Markdown("#### Create a New Account") with gr.Column(): signup_username = gr.Textbox( label="Username", placeholder="Choose a username", type="text" ) signup_email = gr.Textbox( label="Email", placeholder="Enter your email", type="text" ) signup_password = gr.Textbox( label="Password", placeholder="Create a password (min 6 chars)", type="password" ) signup_confirm = gr.Textbox( label="Confirm Password", placeholder="Confirm your password", type="password" ) signup_msg = gr.Textbox( label="✅ Status", interactive=False, visible=False ) signup_btn = gr.Button("✍️ Sign Up", variant="primary", size="lg") # Success notification success_popup = gr.HTML( value="", visible=False ) # CHAT SECTION (shown when logged in) with gr.Group(visible=False) as chat_section: # User info bar with gr.Row(): with gr.Column(scale=4): gr.Markdown("### 💬 Chat Interface") with gr.Column(scale=1): current_user_display = gr.Textbox( label="👤 Logged In As", value=get_current_username(), interactive=False ) with gr.Row(): with gr.Column(scale=3): chatbot_ui = gr.Chatbot( label="💬 Chat History", height=500, show_label=True ) with gr.Column(scale=1): gr.Markdown("### ⚙️ Settings") mode = gr.Radio( choices=["general", "technical", "creative", "educational", "medical"], value="general", label="Chat Mode", info="Select conversation style" ) temperature = gr.Slider( minimum=0, maximum=2, value=0.7, step=0.1, label="Creativity", info="Higher = more creative, Lower = focused" ) with gr.Row(): msg_input = gr.Textbox( placeholder="Type your message here...", label="Your Message", lines=2 ) with gr.Row(): send_btn = gr.Button("✉️ Send", variant="primary", scale=2) clear_btn = gr.Button("🗑️ Clear Chat", scale=1) export_btn = gr.Button("📥 Export", scale=1) logout_btn = gr.Button("🚪 Logout", variant="stop", scale=1) export_output = gr.Textbox( label="📋 Exported Chat (JSON)", interactive=False, visible=False ) gr.Markdown(""" ### 📝 Chat Modes: - **General**: Everyday questions and assistance - **Technical**: Code help and tech support - **Creative**: Storytelling and creative writing - **Educational**: Learning and explanations - **Medical**: Health information """) # === EVENT HANDLERS === # Login handler def handle_login(email: str, password: str): success, message, user = auth_system.login(email, password) if success: current_user["logged_in"] = True current_user["user_data"] = user username = user['username'] if user else "" success_html = f'