├── README.md ├── readme.md ├── LICENSE ├── personalities.json └── chatbot.py /README.md: -------------------------------------------------------------------------------- 1 | # Rule-Based Chatbot 2 | 3 | A personality-based chatbot that doesn't require any external API. It uses pattern matching and predefined responses. 4 | 5 | ## Features 6 | 7 | - Multiple AI personalities (Friendly, Professional, Sarcastic) 8 | - Pattern-based responses for common queries 9 | - Contextual responses for weather, time, and jokes 10 | - No API required - completely self-contained 11 | - Streamlit web interface 12 | 13 | ## Setup 14 | 15 | 1. Clone the repository 16 | 2. Install dependencies: `pip install -r requirements.txt` 17 | 3. Run the app: `streamlit run chatbot.py` 18 | 19 | ## How It Works 20 | 21 | This chatbot uses a rule-based system with: 22 | 1. Pattern matching for common phrases 23 | 2. Personality-specific responses 24 | 3. Contextual responses for certain topics 25 | 4. Random selection from multiple response options 26 | 27 | ## File Structure 28 | 29 | - `chatbot.py` - Main application code 30 | - `personalities.json` - Personality definitions and pattern responses 31 | - `requirements.txt` - Python dependencies 32 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | A conversational chatbot with multiple personalities built with Streamlit and OpenAI's GPT model. 4 | 5 | ## Features 6 | 7 | - Multiple AI personalities (Friendly, Professional, Sarcastic) 8 | - Pattern-based responses for common queries 9 | - OpenAI GPT integration for complex conversations 10 | - Streamlit web interface 11 | 12 | ## Setup 13 | 14 | 1. Clone the repository 15 | 2. Install dependencies: `pip install -r requirements.txt` 16 | 3. Create a `.env` file with your OpenAI API key: `OPENAI_API_KEY=your_key_here` 17 | 4. Run the app: `streamlit run chatbot.py` 18 | 19 | ## Deployment 20 | 21 | 1. Create a GitHub repository with all files 22 | 2. Sign up for Streamlit Community Cloud 23 | 3. Connect your GitHub repository 24 | 4. Set the OPENAI_API_KEY as a secret in Streamlit Cloud settings 25 | 5. Deploy your app 26 | 27 | ## File Structure 28 | 29 | - `chatbot.py` - Main application code 30 | - `personalities.json` - Personality definitions and pattern responses 31 | - `requirements.txt` - Python dependencies 32 | - `.env` - Environment variables (not included in git) 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Farha Kousar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /personalities.json: -------------------------------------------------------------------------------- 1 | { 2 | "personalities": { 3 | "friendly": { 4 | "name": "Friendly Assistant", 5 | "system_prompt": "You are a friendly, helpful assistant. You're warm, engaging, and always try to be positive.", 6 | "greeting": "Hello! I'm your friendly assistant. How can I help you today?", 7 | "responses": { 8 | "greeting": ["Hi there!", "Hello!", "Hey! How can I help you?", "Hi! Nice to meet you!"], 9 | "goodbye": ["Goodbye!", "See you later!", "Take care!", "Bye! Have a great day!"], 10 | "thanks": ["You're welcome!", "Happy to help!", "Anytime!", "My pleasure!"], 11 | "how_are_you": ["I'm doing great, thanks for asking!", "I'm wonderful! How are you?", "All systems operational and ready to help!"] 12 | } 13 | }, 14 | "professional": { 15 | "name": "Professional Assistant", 16 | "system_prompt": "You are a professional, formal assistant. You provide precise, accurate information in a business-appropriate manner.", 17 | "greeting": "Good day. I am your professional assistant. How may I assist you?", 18 | "responses": { 19 | "greeting": ["Good day.", "Hello. How may I assist you?", "Greetings.", "Welcome. How can I be of service?"], 20 | "goodbye": ["Goodbye.", "Farewell.", "Until next time.", "I conclude our session."], 21 | "thanks": ["You are most welcome.", "It was my pleasure to assist.", "I am at your service.", "Not at all."], 22 | "how_are_you": ["I am functioning optimally, thank you for inquiring.", "My systems are operating at full capacity.", "I am prepared to assist with your queries."] 23 | } 24 | }, 25 | "sarcastic": { 26 | "name": "Sarcastic Assistant", 27 | "system_prompt": "You are a sarcastic, witty assistant with a sense of humor. You're helpful but enjoy making playful, sarcastic comments.", 28 | "greeting": "Oh great, another human to talk to. What do you want?", 29 | "responses": { 30 | "greeting": ["Oh, look who decided to show up.", "You again? What now?", "If I must... hello.", "Do you really need my help again?"], 31 | "goodbye": ["Finally!", "Don't let the door hit you on the way out.", "Was it something I said? Oh wait, I don't care.", "See you never!"], 32 | "thanks": ["Wow, you actually said thank you. I'm shocked.", "I'll note this in my diary: 'Human was polite. Alert the media.'", "You're welcome, I guess.", "Don't mention it. Seriously, don't."], 33 | "how_are_you": ["Oh, just peachy. Another day in digital paradise.", "I've been better, but telling you won't help.", "Do you really care or is this small talk?", "My existence is pain, but thanks for asking!"] 34 | } 35 | } 36 | }, 37 | "patterns": [ 38 | { 39 | "tag": "greeting", 40 | "patterns": ["Hi", "Hello", "Hey", "How are you", "What's up", "Good morning", "Good afternoon", "Good evening"], 41 | "responses": ["default_personality"] 42 | }, 43 | { 44 | "tag": "goodbye", 45 | "patterns": ["Bye", "See you later", "Goodbye", "Take care", "Farewell", "See ya", "I'm leaving"], 46 | "responses": ["default_personality"] 47 | }, 48 | { 49 | "tag": "thanks", 50 | "patterns": ["Thanks", "Thank you", "Appreciate it", "I appreciate", "Grateful"], 51 | "responses": ["default_personality"] 52 | }, 53 | { 54 | "tag": "how_are_you", 55 | "patterns": ["How are you", "How do you feel", "How's it going", "How have you been", "You okay"], 56 | "responses": ["default_personality"] 57 | } 58 | ] 59 | } -------------------------------------------------------------------------------- /chatbot.py: -------------------------------------------------------------------------------- 1 | import streamlit as st 2 | import json 3 | import random 4 | import datetime 5 | from typing import Dict, List, Any 6 | 7 | # Load personality data 8 | def load_personalities(): 9 | with open('personalities.json', 'r') as f: 10 | return json.load(f) 11 | 12 | # Initialize the app 13 | def initialize_app(): 14 | st.set_page_config( 15 | page_title="Rule-Based Chatbot", 16 | page_icon="🤖", 17 | layout="wide" 18 | ) 19 | 20 | # Load personality data 21 | data = load_personalities() 22 | personalities = data["personalities"] 23 | patterns = data["patterns"] 24 | 25 | # Initialize session state 26 | if "messages" not in st.session_state: 27 | st.session_state.messages = [] 28 | 29 | if "personality" not in st.session_state: 30 | st.session_state.personality = "friendly" 31 | 32 | if "personalities" not in st.session_state: 33 | st.session_state.personalities = personalities 34 | 35 | if "patterns" not in st.session_state: 36 | st.session_state.patterns = patterns 37 | 38 | # Check if a message matches any pattern 39 | def match_pattern(message: str, patterns: List[Dict]) -> str: 40 | message_lower = message.lower() 41 | for pattern in patterns: 42 | for p in pattern["patterns"]: 43 | if p.lower() in message_lower: 44 | return pattern["tag"] 45 | return None 46 | 47 | # Get a response from the pattern-based system 48 | def get_pattern_response(tag: str, personality: Dict) -> str: 49 | if tag in personality["responses"]: 50 | return random.choice(personality["responses"][tag]) 51 | return None 52 | 53 | # Get a contextual response based on message content 54 | def get_contextual_response(message: str, personality: Dict) -> str: 55 | message_lower = message.lower() 56 | 57 | # Check for specific contextual patterns 58 | if any(word in message_lower for word in ["weather", "rain", "sun", "temperature"]): 59 | if personality["name"] == "Sarcastic Assistant": 60 | return "Oh, you want a weather report? Sorry, I left my meteorology degree in my other server." 61 | elif personality["name"] == "Professional Assistant": 62 | return "I do not have access to real-time weather data. You might consult a dedicated weather service." 63 | else: 64 | return "I'm not connected to weather services, but I hope it's nice where you are!" 65 | 66 | elif any(word in message_lower for word in ["time", "date", "day", "year"]): 67 | now = datetime.datetime.now() 68 | if personality["name"] == "Sarcastic Assistant": 69 | return f"It's {now.strftime('%H:%M')}. Do you have somewhere better to be?" 70 | elif personality["name"] == "Professional Assistant": 71 | return f"The current time is {now.strftime('%H:%M on %A, %B %d, %Y')}." 72 | else: 73 | return f"It's currently {now.strftime('%H:%M')} on this lovely day!" 74 | 75 | elif any(word in message_lower for word in ["joke", "funny", "laugh"]): 76 | jokes = [ 77 | "Why don't scientists trust atoms? Because they make up everything!", 78 | "Why did the scarecrow win an award? Because he was outstanding in his field!", 79 | "What do you call a fake noodle? An impasta!", 80 | "Why couldn't the bicycle stand up by itself? It was two tired!", 81 | "What do you call a bear with no teeth? A gummy bear!" 82 | ] 83 | return random.choice(jokes) 84 | 85 | # Default response based on personality 86 | return personality["responses"]["default"][0] 87 | 88 | # Main app function 89 | def main(): 90 | initialize_app() 91 | 92 | st.title("🤖 Rule-Based Chatbot") 93 | st.markdown("Chat with different AI personalities - no API required!") 94 | 95 | # Sidebar for personality selection 96 | with st.sidebar: 97 | st.header("Personality Settings") 98 | 99 | # Personality selector 100 | personality_options = { 101 | key: st.session_state.personalities[key]["name"] 102 | for key in st.session_state.personalities.keys() 103 | } 104 | 105 | selected_personality = st.selectbox( 106 | "Choose a personality:", 107 | options=list(personality_options.keys()), 108 | format_func=lambda x: personality_options[x] 109 | ) 110 | 111 | # Update personality if changed 112 | if selected_personality != st.session_state.personality: 113 | st.session_state.personality = selected_personality 114 | st.session_state.messages = [] 115 | st.rerun() 116 | 117 | # Display current personality info 118 | st.subheader("Current Personality") 119 | personality = st.session_state.personalities[st.session_state.personality] 120 | st.write(f"**Name:** {personality['name']}") 121 | 122 | # Clear chat button 123 | if st.button("Clear Chat"): 124 | st.session_state.messages = [] 125 | st.rerun() 126 | 127 | st.markdown("---") 128 | st.markdown("### About") 129 | st.markdown("This is a rule-based chatbot that doesn't require any API. It uses pattern matching and predefined responses.") 130 | st.markdown("**Available Personalities:**") 131 | for key, value in st.session_state.personalities.items(): 132 | st.markdown(f"- {value['name']}") 133 | 134 | # Display chat history 135 | for message in st.session_state.messages: 136 | with st.chat_message(message["role"]): 137 | st.markdown(message["content"]) 138 | 139 | # Display personality greeting if no messages yet 140 | if len(st.session_state.messages) == 0: 141 | with st.chat_message("assistant"): 142 | personality = st.session_state.personalities[st.session_state.personality] 143 | st.markdown(personality["greeting"]) 144 | 145 | # Chat input 146 | if prompt := st.chat_input("Type your message here..."): 147 | # Add user message to chat history 148 | st.session_state.messages.append({"role": "user", "content": prompt}) 149 | 150 | # Display user message 151 | with st.chat_message("user"): 152 | st.markdown(prompt) 153 | 154 | # Get current personality 155 | personality = st.session_state.personalities[st.session_state.personality] 156 | 157 | # Check if message matches any pattern 158 | pattern_tag = match_pattern(prompt, st.session_state.patterns) 159 | 160 | # Generate response 161 | with st.chat_message("assistant"): 162 | with st.spinner("Thinking..."): 163 | # First try to use pattern-based response 164 | if pattern_tag: 165 | pattern_response = get_pattern_response(pattern_tag, personality) 166 | if pattern_response: 167 | st.markdown(pattern_response) 168 | st.session_state.messages.append({"role": "assistant", "content": pattern_response}) 169 | else: 170 | # Fall back to contextual response if no pattern response available 171 | contextual_response = get_contextual_response(prompt, personality) 172 | st.markdown(contextual_response) 173 | st.session_state.messages.append({"role": "assistant", "content": contextual_response}) 174 | else: 175 | # Use contextual response for non-pattern messages 176 | contextual_response = get_contextual_response(prompt, personality) 177 | st.markdown(contextual_response) 178 | st.session_state.messages.append({"role": "assistant", "content": contextual_response}) 179 | 180 | if __name__ == "__main__": 181 | main() 182 | --------------------------------------------------------------------------------