Wajahat698 commited on
Commit
9d254e3
·
verified ·
1 Parent(s): 1371e6a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +355 -39
app.py CHANGED
@@ -1,8 +1,14 @@
1
- import logging
 
 
 
 
 
2
  import os
 
 
3
  import requests
4
  from dotenv import load_dotenv
5
- import gradio as gr
6
  import openai
7
  from langchain_openai import ChatOpenAI
8
  from langchain_community.vectorstores import FAISS
@@ -18,6 +24,8 @@ from langchain_community.document_loaders import TextLoader
18
  from langchain_text_splitters import CharacterTextSplitter
19
  import serpapi
20
 
 
 
21
  # Initialize logging
22
  logging.basicConfig(level=logging.INFO)
23
  logger = logging.getLogger(__name__)
@@ -43,8 +51,82 @@ except Exception as e:
43
  logger.error(f"Error initializing OpenAI client: {e}")
44
  raise e
45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
- # Load knowledge base
48
  def load_knowledge_base():
49
  try:
50
  loader = TextLoader("./data_source/time_to_rethink_trust_book.md")
@@ -59,6 +141,8 @@ def load_knowledge_base():
59
 
60
  knowledge_base = load_knowledge_base()
61
 
 
 
62
  # Initialize embeddings and FAISS index
63
  try:
64
  embeddings = OpenAIEmbeddings()
@@ -67,8 +151,7 @@ except Exception as e:
67
  logger.error(f"Error initializing FAISS index: {e}")
68
  raise e
69
 
70
-
71
- # Define search function for knowledge base
72
  def search_knowledge_base(query):
73
  try:
74
  output = db.similarity_search(query)
@@ -79,6 +162,8 @@ def search_knowledge_base(query):
79
 
80
 
81
  # SERPER API Google Search function
 
 
82
  def google_search(query):
83
  try:
84
  search_client = serpapi.Client(api_key=serper_api_key)
@@ -99,6 +184,8 @@ def google_search(query):
99
 
100
 
101
  # RAG response function
 
 
102
  def rag_response(query):
103
  try:
104
  retrieved_docs = search_knowledge_base(query)
@@ -124,7 +211,6 @@ def knowledge_base_tool(query: str):
124
  """
125
  return rag_response(query)
126
 
127
-
128
  @tool
129
  def google_search_tool(query: str):
130
  """
@@ -149,6 +235,7 @@ Engage in a friendly and informative conversation based on the knowledge base.
149
  Only proceed to create sales materials when the user explicitly requests it.
150
  Work together with the user to update the outcome of the sales material.
151
  """
 
152
  prompt_template = ChatPromptTemplate.from_messages(
153
  [
154
  ("system", prompt_message),
@@ -165,7 +252,9 @@ try:
165
  except Exception as e:
166
  logger.error(f"Error creating Langchain Agent: {e}")
167
 
 
168
  # Define the agent pipeline to handle the conversation flow
 
169
  try:
170
  agent = (
171
  {
@@ -187,12 +276,13 @@ except Exception as e:
187
 
188
  # Initialize chat history
189
  chat_history = []
190
-
 
191
 
192
  def chatbot_response(message, history):
193
  try:
194
  # Generate response using the agent executor
195
- output = agent_executor.invoke({"input": message, "chat_history": chat_history})
196
 
197
  # Save the interaction context
198
  chat_history.extend(
@@ -202,44 +292,270 @@ def chatbot_response(message, history):
202
  ]
203
  )
204
 
205
- return output["output"]
 
 
 
 
 
 
206
  except Exception as e:
207
  logger.error(f"Error generating chatbot response: {e}")
208
- return "Error occurred during response generation"
 
 
 
209
 
210
 
211
- # # Define CSS for Gradio interface
212
- # CSS = """
213
- # .contain { display: flex; flex-direction: column; height: 100vh; }
214
- # #component-0 { height: 90%; }
215
- # """
216
 
217
- # # Gradio interface
218
- # with gr.Blocks(css=CSS) as demo:
219
 
220
- submit_button = gr.Button("Submit")
 
 
 
 
 
221
 
222
- bot = gr.Chatbot()
223
 
224
- with gr.Blocks() as demo:
225
- gr.Markdown(
226
- "<span style='font-size:20px; font-weight:bold;'>Instant Insight-2-Action</span>",
227
- visible=True,
228
- )
229
 
230
- chatbot = gr.ChatInterface(
231
- fn=chatbot_response,
232
- stop_btn=None,
233
- retry_btn=None,
234
- undo_btn=None,
235
- clear_btn=None,
236
- submit_btn=submit_button,
237
- chatbot=bot,
238
- )
239
 
240
- # Launch the Gradio app
241
- try:
242
- demo.launch(server_name="0.0.0.0")
243
- except Exception as e:
244
- logger.error(f"Error launching Gradio app: {e}")
245
- raise e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import openai
2
+ import streamlit as st
3
+ import streamlit.components.v1 as components
4
+ import smtplib
5
+ from email.mime.multipart import MIMEMultipart
6
+ from email.mime.text import MIMEText
7
  import os
8
+
9
+ import logging
10
  import requests
11
  from dotenv import load_dotenv
 
12
  import openai
13
  from langchain_openai import ChatOpenAI
14
  from langchain_community.vectorstores import FAISS
 
24
  from langchain_text_splitters import CharacterTextSplitter
25
  import serpapi
26
 
27
+
28
+
29
  # Initialize logging
30
  logging.basicConfig(level=logging.INFO)
31
  logger = logging.getLogger(__name__)
 
51
  logger.error(f"Error initializing OpenAI client: {e}")
52
  raise e
53
 
54
+ EMAIL_ADDRESS = os.getenv("EMAIL_ADDRESS")
55
+ EMAIL_PASSWORD = os.getenv("EMAIL_PASSWORD")
56
+ SMTP_SERVER = "mail.privateemail.com"
57
+ SMTP_PORT = 587
58
+ st.markdown("""
59
+ <style>
60
+ .custom-image img {
61
+ width: 100px; /* Set the width to make the image smaller */
62
+ height: auto; /* Keep the aspect ratio */
63
+ }
64
+ </style>
65
+ """, unsafe_allow_html=True)
66
+ def copy_to_clipboard(text):
67
+ """Creates a button to copy text to clipboard."""
68
+ escaped_text = text.replace('\n', '\\n').replace('"', '\\"')
69
+ copy_icon_html = f"""
70
+ <style>
71
+ .copy-container {{
72
+ position: relative;
73
+ margin-top: 10px;
74
+ padding-bottom: 30px; /* Space for the button */
75
+ font-size: 0; /* Hide extra space */
76
+ }}
77
+ .copy-button {{
78
+ background: none;
79
+ border: none;
80
+ color: #808080; /* Grey color */
81
+ cursor: pointer;
82
+ font-size: 18px; /* Adjust icon size */
83
+ position: absolute;
84
+ bottom: 0;
85
+ right: 0;
86
+ }}
87
+ .copy-button:hover {{
88
+ color: #606060; /* Darker grey on hover */
89
+ }}
90
+ .copy-message {{
91
+ font-size: 12px;
92
+ color: #4CAF50;
93
+ margin-left: 10px;
94
+ display: none;
95
+ }}
96
+ </style>
97
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css">
98
+ <div class="copy-container">
99
+ <button class="copy-button" onclick="copyToClipboard()">
100
+ <i class="fas fa-copy"></i>
101
+ </button>
102
+ <span class="copy-message" id="copy_message">Copied!</span>
103
+ </div>
104
+
105
+ <script>
106
+ function copyToClipboard() {{
107
+ var textArea = document.createElement("textarea");
108
+ textArea.value = "{escaped_text}";
109
+ document.body.appendChild(textArea);
110
+ textArea.select();
111
+ document.execCommand("copy");
112
+ document.body.removeChild(textArea);
113
+
114
+ var copyMessage = document.getElementById("copy_message");
115
+ copyMessage.style.display = "inline";
116
+ setTimeout(function() {{
117
+ copyMessage.style.display = "none";
118
+ }}, 2000);
119
+ }}
120
+ </script>
121
+ """
122
+ components.html(copy_icon_html, height=60)
123
+
124
+
125
+
126
+
127
+
128
+
129
 
 
130
  def load_knowledge_base():
131
  try:
132
  loader = TextLoader("./data_source/time_to_rethink_trust_book.md")
 
141
 
142
  knowledge_base = load_knowledge_base()
143
 
144
+
145
+
146
  # Initialize embeddings and FAISS index
147
  try:
148
  embeddings = OpenAIEmbeddings()
 
151
  logger.error(f"Error initializing FAISS index: {e}")
152
  raise e
153
 
154
+ #Define search function for knowledge base
 
155
  def search_knowledge_base(query):
156
  try:
157
  output = db.similarity_search(query)
 
162
 
163
 
164
  # SERPER API Google Search function
165
+
166
+
167
  def google_search(query):
168
  try:
169
  search_client = serpapi.Client(api_key=serper_api_key)
 
184
 
185
 
186
  # RAG response function
187
+
188
+
189
  def rag_response(query):
190
  try:
191
  retrieved_docs = search_knowledge_base(query)
 
211
  """
212
  return rag_response(query)
213
 
 
214
  @tool
215
  def google_search_tool(query: str):
216
  """
 
235
  Only proceed to create sales materials when the user explicitly requests it.
236
  Work together with the user to update the outcome of the sales material.
237
  """
238
+
239
  prompt_template = ChatPromptTemplate.from_messages(
240
  [
241
  ("system", prompt_message),
 
252
  except Exception as e:
253
  logger.error(f"Error creating Langchain Agent: {e}")
254
 
255
+
256
  # Define the agent pipeline to handle the conversation flow
257
+
258
  try:
259
  agent = (
260
  {
 
276
 
277
  # Initialize chat history
278
  chat_history = []
279
+ if "messages" not in st.session_state:
280
+ st.session_state.messages = []
281
 
282
  def chatbot_response(message, history):
283
  try:
284
  # Generate response using the agent executor
285
+ output = agent_executor.invoke({"input": message, "chat_history": st.session_state.messages})
286
 
287
  # Save the interaction context
288
  chat_history.extend(
 
292
  ]
293
  )
294
 
295
+ # Generate follow-up suggestions
296
+ suggestions = get_suggestions(output["output"])
297
+
298
+ return {
299
+ "response": output["output"],
300
+ "suggestions": suggestions
301
+ }
302
  except Exception as e:
303
  logger.error(f"Error generating chatbot response: {e}")
304
+ return {
305
+ "response": "Error occurred during response generation",
306
+ "suggestions": "Error occurred while generating suggestions"
307
+ }
308
 
309
 
 
 
 
 
 
310
 
 
 
311
 
312
+ def get_suggestions(response_text):
313
+ """Generates follow-up questions or suggestions based on the response text."""
314
+ prompt = f"{response_text}\n\nWhat follow-up questions would you give related to this topic?"
315
+ llm = ChatOpenAI(model="gpt-4o", temperature=0.5, api_key=openai_api_key)
316
+ response = llm.invoke(prompt)
317
+ return response.content
318
 
 
319
 
320
+ def start_chat():
321
+ st.session_state.chat_started = True
 
 
 
322
 
 
 
 
 
 
 
 
 
 
323
 
324
+
325
+
326
+ def feedback_email(name, email, feedback):
327
+ """Sends feedback via email."""
328
+ recipient_email = "wajahat698@gmail.com"
329
+ msg = MIMEMultipart()
330
+ msg['From'] = EMAIL_ADDRESS
331
+ msg['To'] = recipient_email
332
+ msg['Subject'] = "Feedback"
333
+ msg.attach(MIMEText(feedback, 'plain'))
334
+
335
+ try:
336
+ with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server:
337
+ server.starttls()
338
+ server.login(EMAIL_ADDRESS, EMAIL_PASSWORD)
339
+ server.sendmail(EMAIL_ADDRESS, recipient_email, msg.as_string())
340
+ except Exception as e:
341
+ st.error(f"Error sending email: {e}")
342
+
343
+
344
+ def create_section(title, content, example=None, dark_mode=False):
345
+ text_color = "#afafaf" if dark_mode else "#333333"
346
+ border_color = "#afafaf" if dark_mode else "#afafaf"
347
+
348
+ example_html = f"""<p style="color: {text_color}; font-size: 12px; margin: 5px 0;">{example}</p>""" if example else ''
349
+
350
+ section_html = f"""
351
+ <div style="
352
+ flex: 1;
353
+ min-width: 180px;
354
+ max-width: 220px;
355
+ min-height: 150px;
356
+ border: 1px solid {border_color};
357
+ border-radius: 10px;
358
+ padding: 10px;
359
+ background-color: transparent;
360
+ margin: 5px;
361
+ text-align: center;
362
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
363
+ box-sizing: border-box;
364
+ font-size: 12px;
365
+ ">
366
+ <h2 style="
367
+ color: {text_color};
368
+ font-size: 14px;
369
+ margin-bottom: 8px;
370
+ border-bottom: 1px solid {border_color};
371
+ padding-bottom: 4px;
372
+ ">{title}</h2>
373
+ <p style="
374
+ color: {text_color};
375
+ font-size: 11px;
376
+ margin: 5px 0;
377
+ line-height: 1.4;
378
+ ">{content}</p>
379
+ {example_html}
380
+ </div>
381
+ """
382
+
383
+ return section_html
384
+
385
+
386
+ # Sidebar for feedback form
387
+ with st.sidebar.form(key='feedback_form'):
388
+
389
+ st.image( "Trust Logic_Wheel_RGB_Standard.png")
390
+ st.header("Let's create something great.")
391
+ st.markdown("Our minds assess trust through Six Buckets of Trust® and determine their importance and order in a given situation. We then evaluate why we can or can’t trust someone in these Buckets. TrustAI®, trained on 20 years of TrustLogic® application, helps you identify reasons why your audience can trust you in each Bucket and create trust-optimised solutions. It’s copy AI with substance.")
392
+ st.markdown("""
393
+ <style>
394
+ .stability { color: rgb(7, 55, 99); font-size: 24px; font-weight: bold; }
395
+ .development { color: rgb(241, 194, 50); font-size: 24px; font-weight: bold; }
396
+ .relationship { color: rgb(204, 0, 0); font-size: 24px; font-weight: bold; }
397
+ .benefit { color: rgb(56, 118, 29); font-size: 24px; font-weight: bold; }
398
+ .vision { color: rgb(255, 153, 0); font-size: 24px; font-weight: bold; }
399
+ .competence { color: rgb(111, 168, 220); font-size: 24px; font-weight: bold; }
400
+ </style>
401
+
402
+ <h3 class="stability">Stability Trust:</h3>
403
+ <p>Why can I trust you to have built a strong and stable foundation?</p>
404
+
405
+ <h3 class="development">Development Trust:</h3>
406
+ <p>Why can I trust you to develop well in the future?</p>
407
+
408
+ <h3 class="relationship">Relationship Trust:</h3>
409
+ <p>What appealing relationship qualities can I trust you for?</p>
410
+
411
+ <h3 class="benefit">Benefit Trust:</h3>
412
+ <p>What benefits can I trust you for?</p>
413
+
414
+ <h3 class="vision">Vision Trust:</h3>
415
+ <p>What Vision and Values can I trust you for?</p>
416
+
417
+ <h3 class="competence">Competence Trust:</h3>
418
+ <p>What competencies can I trust you for?</p>
419
+ """, unsafe_allow_html=True)
420
+ st.markdown("For detailed descriptions, visit [Academy](https://www.trustlogic.info/academy)")
421
+
422
+
423
+
424
+
425
+
426
+ feedback_name = st.text_input("Name")
427
+ feedback_email_input = st.text_input("Email")
428
+ feedback_text = st.text_area("Feedback")
429
+
430
+ # Submit button within the form
431
+ submit_button = st.form_submit_button("Submit Feedback")
432
+ if submit_button:
433
+ if feedback_name and feedback_email_input and feedback_text:
434
+ feedback_email(feedback_name, feedback_email_input, feedback_text)
435
+ st.success("Thank you for your feedback!")
436
+ else:
437
+ st.error("Please fill in all fields.")
438
+
439
+
440
+
441
+ if "chat_started" not in st.session_state:
442
+ st.session_state.chat_started = False
443
+
444
+
445
+
446
+
447
+
448
+ # Show the message and carousel only if the chat hasn't started
449
+ if not st.session_state.chat_started:
450
+ st.markdown("""
451
+ <script>
452
+ document.addEventListener('DOMContentLoaded', (event) => {
453
+ const svgs = document.querySelectorAll('svg');
454
+ svgs.forEach(svg => {
455
+ if (svg.getAttribute('xmlns') === 'http://www.w3.org/2000/svg' && svg.getAttribute('width') === '18' && svg.getAttribute('height') === '18') {
456
+ svg.style.display = 'none';
457
+ }
458
+ });
459
+ });
460
+ </script>
461
+
462
+ <style>
463
+ /* Hide all <a> elements inside elements with block-container and st-emotion-cache-1eo1tir ea3mdgi5 classes */
464
+ .block-container.st-emotion-cache-1eo1tir.ea3mdgi5 a {
465
+ display: none !important;
466
+ }
467
+
468
+ /* Ensure links in the sidebar are visible and underlined */
469
+ .stSidebar a {
470
+ display: inline !important;
471
+ text-decoration: underline !important;
472
+ color: inherit !important;
473
+ }
474
+
475
+ /* Additional styles */
476
+ .section-container {
477
+ display: flex;
478
+ justify-content: center;
479
+ align-items: stretch;
480
+ flex-wrap: wrap;
481
+ gap: 4px;
482
+ }
483
+
484
+ .section {
485
+ flex: 1;
486
+ min-width: 150px;
487
+ max-width: 90px;
488
+ min-height: 150px;
489
+ border: 1px solid #afafaf;
490
+ border-radius: 10px;
491
+ padding: 5px;
492
+ background-color: transparent;
493
+ margin: 3px;
494
+ text-align: center;
495
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
496
+ box-sizing: border-box;
497
+ font-size: 12px;
498
+ transition: background-color 0.3s ease;
499
+ }
500
+
501
+ .section h2 {
502
+ color: #afafaf;
503
+ font-size: 14px;
504
+ margin-bottom: 8px;
505
+ border-bottom: 1px solid #afafaf;
506
+ padding-bottom: 4px;
507
+ }
508
+
509
+ .section p {
510
+ color: #afafaf;
511
+ font-size: 11px;
512
+ margin: 5px 0;
513
+ line-height: 1.4;
514
+ }
515
+
516
+ @media (max-width: 100px) {
517
+ .section {
518
+ min-width: 90%;
519
+ max-width: 90%;
520
+ }
521
+ }
522
+ </style>
523
+
524
+ <h1 style='text-align: center; color: #b4b4b4;'>How can I help you today?</h1>
525
+
526
+ <div class="section-container">
527
+ <div class="section">
528
+ <h2>Find</h2>
529
+ <p>Discover all your great TrustBuilders®. <br> Example: Find Development Trust Builders® for World Vision
530
+ </div>
531
+ <div class="section">
532
+ <h2>Create</h2>
533
+ <p>Generate trust-optimised solutions: <br>Example: Find World Vision development TrustBuilders®. Then use them to write a 200-word annual report article. Enthusiastic tone.</p>
534
+ </div>
535
+ <div class="section">
536
+ <h2>Trust-optimise</h2>
537
+ <p>Paste your LinkedIn profile, EDM or blog and ask TrustAI® to improve it using specific Trust Buckets® and add your specific TrustBuilders® as examples.</p>
538
+ </div>
539
+ </div>
540
+ """, unsafe_allow_html=True)
541
+
542
+ # Input field for user messages
543
+ if prompt := st.chat_input("Type your prompt here"):
544
+ start_chat()
545
+
546
+ if prompt := st.chat_input("Type your prompt here"):
547
+ st.session_state.chat_started = True # Mark that chat has started
548
+ st.session_state.messages.append({"role": "user", "content": prompt})
549
+
550
+ # Generate response and suggestions using GPT
551
+ response = chatbot_response(prompt, st.session_state.messages)
552
+
553
+ st.session_state.messages.append({"role": "assistant", "content": response["response"]})
554
+ st.session_state.messages.append({"role": "assistant", "content": f"**Suggestions:**\n{response['suggestions']}"})
555
+
556
+ if st.session_state.chat_started:
557
+ for msg in st.session_state.messages:
558
+ st.chat_message(msg["role"]).write(msg["content"])
559
+ if msg["role"] == "assistant":
560
+ copy_to_clipboard(msg["content"])
561
+