Uamir commited on
Commit
2f8328d
Β·
verified Β·
1 Parent(s): 29409ed

Upload 4 files

Browse files
Files changed (4) hide show
  1. .env +1 -0
  2. app.py +314 -0
  3. chatbot_backend.py +42 -0
  4. requirements.txt +8 -0
.env ADDED
@@ -0,0 +1 @@
 
 
1
+ GOOGLE_API_KEY = "AIzaSyCUFtCffTda7YwUeb4nsY3at4Y99msnL1E"
app.py ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from datetime import datetime
3
+ from chatbot_backend import ask_bot
4
+
5
+ # --- Page Configuration and Custom CSS ---
6
+ # Using an absolute container for the chat input to keep it at the bottom.
7
+ # This avoids the need for a separate footer and keeps the layout tight.
8
+ st.set_page_config(
9
+ page_title="AI Customer Service Bot",
10
+ page_icon="πŸ€–",
11
+ layout="wide",
12
+ initial_sidebar_state="expanded"
13
+ )
14
+
15
+ st.markdown("""
16
+ <style>
17
+ /* General app background */
18
+ .stApp {
19
+ background-color: #0f1419;
20
+ color: #ffffff;
21
+ }
22
+
23
+ /* Header styling */
24
+ .chat-header {
25
+ text-align: center;
26
+ font-size: 1.5rem; /* Smaller font size */
27
+ font-weight: 700;
28
+ margin-bottom: 1rem; /* Smaller margin */
29
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
30
+ -webkit-background-clip: text;
31
+ -webkit-text-fill-color: transparent;
32
+ }
33
+
34
+ /* Message bubble styling */
35
+ .user-message, .bot-message {
36
+ padding: 0.75rem 1rem; /* Smaller padding */
37
+ border-radius: 15px; /* Smaller rounded corners */
38
+ font-size: 14px; /* Smaller font size */
39
+ line-height: 1.4;
40
+ margin: 0.25rem 0; /* Smaller margin between messages */
41
+ max-width: 75%;
42
+ word-wrap: break-word;
43
+ }
44
+
45
+ .user-message {
46
+ background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
47
+ color: white;
48
+ margin-left: auto;
49
+ border-radius: 15px 15px 5px 15px;
50
+ box-shadow: 0 2px 10px rgba(79, 172, 254, 0.2);
51
+ }
52
+
53
+ .bot-message {
54
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
55
+ color: white;
56
+ margin-right: auto;
57
+ border-radius: 15px 15px 15px 5px;
58
+ box-shadow: 0 2px 10px rgba(102, 126, 234, 0.2);
59
+ }
60
+
61
+ .message-time {
62
+ font-size: 0.65rem; /* Smaller time font */
63
+ opacity: 0.6;
64
+ margin-top: 0.25rem;
65
+ }
66
+
67
+ .user-time { text-align: right; }
68
+ .bot-time { text-align: left; }
69
+
70
+ /* Input and button styling */
71
+ .stTextInput > div > div > input {
72
+ background-color: #1a1a1a;
73
+ color: white;
74
+ border: 1px solid #333; /* Thinner border */
75
+ border-radius: 20px; /* Smaller rounded corners */
76
+ padding: 10px 15px; /* Smaller padding */
77
+ font-size: 14px; /* Smaller font size */
78
+ transition: all 0.2s ease;
79
+ }
80
+
81
+ .stTextInput > div > div > input:focus {
82
+ border-color: #667eea;
83
+ box-shadow: 0 0 5px rgba(102, 126, 234, 0.2);
84
+ }
85
+
86
+ .stButton > button {
87
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
88
+ color: white;
89
+ border: none;
90
+ border-radius: 40px; /* Smaller button */
91
+ padding: 0.5rem 1.5rem; /* Smaller padding */
92
+ font-weight: 600;
93
+ font-size: 14px;
94
+ transition: all 0.2s ease;
95
+ box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
96
+ }
97
+
98
+ .stButton > button:hover {
99
+ transform: translateY(-1px);
100
+ box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
101
+ }
102
+
103
+ /* Sidebar styling */
104
+ .sidebar .stButton > button {
105
+ background: linear-gradient(135deg, #ff6b6b 0%, #ee5a24 100%);
106
+ width: 100%;
107
+ border-radius: 10px;
108
+ margin-bottom: 10px;
109
+ }
110
+
111
+ .chat-stats {
112
+ background: rgba(255, 255, 255, 0.05);
113
+ padding: 0.75rem; /* Smaller padding */
114
+ border-radius: 8px; /* Smaller corners */
115
+ margin: 0.5rem 0;
116
+ backdrop-filter: blur(10px);
117
+ border: 1px solid rgba(255, 255, 255, 0.1);
118
+ font-size: 12px; /* Smaller font size */
119
+ }
120
+
121
+ .welcome-msg {
122
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
123
+ color: white;
124
+ padding: 1rem; /* Smaller padding */
125
+ border-radius: 10px;
126
+ margin: 0.5rem 0;
127
+ text-align: center;
128
+ box-shadow: 0 2px 10px rgba(102, 126, 234, 0.3);
129
+ font-size: 14px; /* Smaller font size */
130
+ }
131
+
132
+ /* New style for Quick Questions to make them smaller and inline */
133
+ .quick-questions-container {
134
+ display: flex;
135
+ flex-wrap: wrap;
136
+ gap: 5px;
137
+ margin-bottom: 10px;
138
+ }
139
+
140
+ .quick-questions-container .stButton > button {
141
+ background: rgba(102, 126, 234, 0.1) !important;
142
+ border: 1px solid #667eea !important;
143
+ color: #667eea !important;
144
+ border-radius: 15px !important;
145
+ padding: 5px 10px !important; /* Even smaller padding for these buttons */
146
+ font-size: 12px !important; /* Smaller font size */
147
+ transition: all 0.3s ease !important;
148
+ flex-grow: 1; /* Allow buttons to grow to fill space */
149
+ min-width: fit-content;
150
+ }
151
+
152
+ .quick-questions-container .stButton > button:hover {
153
+ background: rgba(102, 126, 234, 0.2) !important;
154
+ transform: translateY(-1px) !important;
155
+ }
156
+ </style>
157
+ """, unsafe_allow_html=True)
158
+
159
+ # --- Session State and UI Functions ---
160
+
161
+ def initialize_session_state():
162
+ """Initialize session state variables"""
163
+ if "messages" not in st.session_state:
164
+ st.session_state.messages = []
165
+ welcome = """πŸŽ‰ Welcome to AI Customer Service!
166
+
167
+ I'm your intelligent assistant, ready to help you with any questions or concerns. I have access to our comprehensive knowledge base and can provide detailed, accurate information.
168
+
169
+ Feel free to ask me anything! πŸ’¬"""
170
+
171
+ st.session_state.messages.append({
172
+ "role": "assistant",
173
+ "content": welcome,
174
+ "timestamp": datetime.now().strftime("%H:%M")
175
+ })
176
+
177
+ if "input_counter" not in st.session_state:
178
+ st.session_state.input_counter = 0
179
+
180
+ def display_chat_messages():
181
+ """Display all chat messages"""
182
+ for message in st.session_state.messages:
183
+ if message["role"] == "user":
184
+ st.markdown(f"""
185
+ <div class="user-message">
186
+ πŸ’­ {message["content"]}
187
+ <div class="message-time user-time">You β€’ {message["timestamp"]}</div>
188
+ </div>
189
+ """, unsafe_allow_html=True)
190
+ else:
191
+ st.markdown(f"""
192
+ <div class="bot-message">
193
+ πŸ€– {message["content"]}
194
+ <div class="message-time bot-time">AI Assistant β€’ {message["timestamp"]}</div>
195
+ </div>
196
+ """, unsafe_allow_html=True)
197
+
198
+ st.markdown("", unsafe_allow_html=True) # Small gap between messages
199
+
200
+ def handle_user_input():
201
+ """Handle user input and generate bot response"""
202
+ col1, col2 = st.columns([4, 1])
203
+
204
+ with col1:
205
+ user_input = st.text_input(
206
+ "",
207
+ placeholder="πŸ’¬ Type your question here...",
208
+ key=f"user_input_{st.session_state.input_counter}",
209
+ label_visibility="collapsed"
210
+ )
211
+
212
+ with col2:
213
+ send_clicked = st.button("Send ➀", type="primary")
214
+
215
+ if (send_clicked or user_input) and user_input.strip():
216
+ process_message(user_input.strip())
217
+
218
+ def process_message(user_message):
219
+ """Process user message and get bot response"""
220
+ st.session_state.messages.append({
221
+ "role": "user",
222
+ "content": user_message,
223
+ "timestamp": datetime.now().strftime("%H:%M")
224
+ })
225
+
226
+ with st.spinner("πŸ€– AI is thinking..."):
227
+ try:
228
+ bot_response = ask_bot(user_message)
229
+ except Exception as e:
230
+ bot_response = f"❌ Sorry, I encountered an error: {str(e)}"
231
+
232
+ st.session_state.messages.append({
233
+ "role": "assistant",
234
+ "content": bot_response,
235
+ "timestamp": datetime.now().strftime("%H:%M")
236
+ })
237
+
238
+ st.session_state.input_counter += 1
239
+ st.rerun()
240
+
241
+ def create_sidebar():
242
+ """Create sidebar with controls and quick actions"""
243
+ with st.sidebar:
244
+ st.markdown("## πŸŽ›οΈ Chat Controls")
245
+ if st.button("πŸ—‘οΈ Clear Chat", type="secondary"):
246
+ st.session_state.messages = []
247
+ st.session_state.input_counter = 0
248
+ welcome = """πŸŽ‰ Welcome to AI Customer Service!
249
+ I'm your intelligent assistant, ready to help you with any questions or concerns. I have access to our comprehensive knowledge base and can provide detailed, accurate information.
250
+ Feel free to ask me anything! πŸ’¬"""
251
+ st.session_state.messages.append({
252
+ "role": "assistant",
253
+ "content": welcome,
254
+ "timestamp": datetime.now().strftime("%H:%M")
255
+ })
256
+ st.rerun()
257
+
258
+ st.markdown("---")
259
+ st.markdown("## ⚑ Quick Questions")
260
+
261
+ quick_questions = [
262
+ "What services do you provide?",
263
+ "What are your pricing packages?",
264
+ "What are your business hours?",
265
+ "How can I contact support?",
266
+ "What is your refund policy?"
267
+ ]
268
+
269
+ # Use columns to make buttons appear in a row
270
+ cols = st.columns(2)
271
+
272
+ for i, question in enumerate(quick_questions):
273
+ with cols[i % 2]: # Distribute buttons into two columns
274
+ if st.button(f"πŸ’‘ {question}", key=f"quick_{i}"):
275
+ process_message(question)
276
+
277
+ st.markdown("---")
278
+ st.markdown("## πŸ“Š Chat Statistics")
279
+ st.markdown(f"""
280
+ <div class="chat-stats">
281
+ <strong>Total Messages:</strong> {len(st.session_state.messages)}<br>
282
+ <strong>Your Questions:</strong> {len([m for m in st.session_state.messages if m['role'] == 'user'])}<br>
283
+ <strong>AI Responses:</strong> {len([m for m in st.session_state.messages if m['role'] == 'assistant'])}
284
+ </div>
285
+ """, unsafe_allow_html=True)
286
+
287
+ def main():
288
+ """Main app function"""
289
+ initialize_session_state()
290
+
291
+ st.markdown('<h1 class="chat-header">πŸ€– AI Customer Service Assistant</h1>', unsafe_allow_html=True)
292
+
293
+ create_sidebar()
294
+
295
+ # Main chat area with fixed height and a scrollbar
296
+ chat_container = st.container()
297
+ with chat_container:
298
+ st.markdown("---")
299
+ display_chat_messages()
300
+
301
+ # Input field at the bottom of the page
302
+ st.markdown("---")
303
+ handle_user_input()
304
+
305
+ # Footer
306
+ st.markdown(
307
+ "<div style='text-align: center; color: #666; padding: 0.5rem;'>"
308
+ "πŸ€– Powered by AI β€’ Built with Streamlit β€’ Always here to help!"
309
+ "</div>",
310
+ unsafe_allow_html=True
311
+ )
312
+
313
+ if __name__ == "__main__":
314
+ main()
chatbot_backend.py ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain_google_genai import ChatGoogleGenerativeAI, GoogleGenerativeAIEmbeddings
2
+ from langchain_community.document_loaders import TextLoader
3
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
4
+ from langchain_community.vectorstores import FAISS
5
+ from langchain.memory import ConversationBufferMemory
6
+ from langchain.chains import ConversationalRetrievalChain
7
+ from dotenv import load_dotenv
8
+
9
+ load_dotenv()
10
+
11
+ # Memory
12
+ memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
13
+
14
+ # LLM
15
+ llm = ChatGoogleGenerativeAI(model="gemini-2.5-flash")
16
+
17
+ # Load + Split Docs
18
+ loader = TextLoader("data.txt", encoding="utf-8")
19
+ docs = loader.load()
20
+ splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
21
+ chunks = splitter.split_documents(docs)
22
+
23
+ # Embeddings + VectorStore
24
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
25
+ vectorstore = FAISS.from_documents(documents=chunks, embedding=embeddings)
26
+ retriever = vectorstore.as_retriever(search_kwargs={"k": 2})
27
+
28
+ # Conversational Retrieval Chain (with memory)
29
+ conversational_chain = ConversationalRetrievalChain.from_llm(
30
+ llm=llm,
31
+ retriever=retriever,
32
+ memory=memory,
33
+ return_source_documents=False
34
+ )
35
+
36
+ # βœ… Ask bot function
37
+ def ask_bot(query: str) -> str:
38
+ try:
39
+ response = conversational_chain.invoke({"question": query})
40
+ return response["answer"]
41
+ except Exception as e:
42
+ return f"Error: {str(e)}"
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ langchain
2
+ langchain-community
3
+ langchain-openai
4
+ chromadb
5
+ faiss-cpu
6
+ openai
7
+ tiktoken
8
+ python-dotenv