Wajahat698 commited on
Commit
5e4843b
·
verified ·
1 Parent(s): 216bca9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +595 -128
app.py CHANGED
@@ -1,6 +1,6 @@
1
  import logging
2
  import os
3
- import streamlit as st
4
  from dotenv import load_dotenv
5
  import openai
6
  from langchain_openai import ChatOpenAI
@@ -14,7 +14,7 @@ from langchain_core.messages import AIMessage, HumanMessage
14
  from langchain_community.document_loaders import TextLoader
15
  from langchain_text_splitters import CharacterTextSplitter
16
  import serpapi
17
- import requests
18
  import streamlit.components.v1 as components
19
  import smtplib
20
  from email.mime.multipart import MIMEMultipart
@@ -27,14 +27,126 @@ import smtplib
27
  from email.mime.multipart import MIMEMultipart
28
  from email.mime.text import MIMEText
29
  from markdownify import markdownify
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
  # Initialize logging and load environment variables
32
  logging.basicConfig(level=logging.INFO)
33
  logger = logging.getLogger(__name__)
34
  load_dotenv()
35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  # Define and validate API keys
40
  openai_api_key = os.getenv("OPENAI_API_KEY")
@@ -66,7 +178,11 @@ if 'used_trust_tips' not in st.session_state:
66
  st.session_state.used_trust_tips = set()
67
  if 'used_suggestions' not in st.session_state:
68
  st.session_state.used_suggestions = set()
69
-
 
 
 
 
70
  def copy_to_clipboard(text):
71
  """Creates a button to copy text to clipboard."""
72
  escaped_text = text.replace('\n', '\\n').replace('"', '\\"')
@@ -124,8 +240,7 @@ def copy_to_clipboard(text):
124
  </script>
125
  """
126
  components.html(copy_icon_html, height=60)
127
-
128
-
129
  def send_feedback_via_email(name, email, feedback):
130
  """Sends an email with feedback details."""
131
  smtp_server = 'smtp.office365.com'
@@ -203,7 +318,7 @@ def clean_text(text):
203
  return cleaned_text
204
 
205
 
206
-
207
 
208
 
209
  def get_trust_tip_and_suggestion():
@@ -213,15 +328,152 @@ def get_trust_tip_and_suggestion():
213
 
214
 
215
 
 
 
 
 
 
 
 
 
216
 
 
 
 
 
 
 
217
 
218
- def side():
219
- with st.sidebar.form(key='feedback_form'):
 
 
 
 
220
 
221
- st.image( "Trust Logic_Wheel_RGB_Standard.png")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
222
  st.header("Let's create something great.")
223
- 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. Trustifier.ai®, 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.")
224
- st.markdown("""
 
 
 
 
 
225
  <style>
226
  .stability { color: rgb(7, 55, 99); font-size: 24px; font-weight: bold; }
227
  .development { color: rgb(241, 194, 50); font-size: 24px; font-weight: bold; }
@@ -230,76 +482,80 @@ def side():
230
  .vision { color: rgb(255, 153, 0); font-size: 24px; font-weight: bold; }
231
  .competence { color: rgb(111, 168, 220); font-size: 24px; font-weight: bold; }
232
  </style>
233
-
234
  <h3 class="stability">Stability Trust:</h3>
235
  <p>Why can I trust you to have built a strong and stable foundation?</p>
236
-
237
  <h3 class="development">Development Trust:</h3>
238
  <p>Why can I trust you to develop well in the future?</p>
239
-
240
  <h3 class="relationship">Relationship Trust:</h3>
241
  <p>What appealing relationship qualities can I trust you for?</p>
242
-
243
  <h3 class="benefit">Benefit Trust:</h3>
244
  <p>What benefits can I trust you for?</p>
245
-
246
  <h3 class="vision">Vision Trust:</h3>
247
  <p>What Vision and Values can I trust you for?</p>
248
-
249
  <h3 class="competence">Competence Trust:</h3>
250
  <p>What competencies can I trust you for?</p>
251
- """, unsafe_allow_html=True)
252
- st.markdown("For detailed descriptions, visit [Academy](https://www.trustifier.ai/account/academy)")
253
-
254
-
255
-
256
-
257
-
258
- feedback_name = st.text_input("Name")
259
- feedback_email_input = st.text_input("Email")
260
- feedback_text = st.text_area("Feedback")
261
-
262
- # Submit button within the form
263
- submit_button = st.form_submit_button("Submit Feedback")
264
- if submit_button:
265
- if feedback_name and feedback_email_input and feedback_text:
266
- with st.spinner('Sending email'):
267
- send_feedback_via_email(feedback_name, feedback_email_input, feedback_text)
268
- st.success("Thank you for your feedback!")
269
- else:
270
- st.error("Please fill in all fields.")
271
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
 
273
 
274
 
275
  side()
276
  # Load knowledge base
277
- def load_knowledge_base():
278
- try:
279
- loader = TextLoader("./data_source/time_to_rethink_trust_book.md")
280
- documents = loader.load()
281
- text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
282
- docs = text_splitter.split_documents(documents)
283
- return docs
284
- except Exception as e:
285
- logger.error(f"Error loading knowledge base: {e}")
286
- raise e
287
 
288
- knowledge_base = load_knowledge_base()
289
 
290
- # Initialize embeddings and FAISS index
291
- embeddings = OpenAIEmbeddings()
292
- db = FAISS.from_documents(knowledge_base, embeddings)
 
 
293
 
294
  # Define search functions
295
  def search_knowledge_base(query):
296
- try:
297
- output = db.similarity_search(query)
298
- return output
299
- except Exception as e:
300
- logger.error(f"Error searching knowledge base: {e}")
301
- return ["Error occurred during knowledge base search"]
302
-
 
 
 
 
 
303
  def google_search(query):
304
  try:
305
  search_client = serpapi.Client(api_key=serper_api_key)
@@ -347,6 +603,7 @@ tools = [knowledge_base_tool, google_search_tool]
347
 
348
  prompt_message = f"""
349
  **You are an expert copywriter specializing in creating highly creative marketing content in natural tone that integrates **Trust Builders** into various content formats for any organization. Your goal is to produce compelling, factual,and well-structured material that is concise and based on the knowledgebase, adhering to the following guidelines.The content should be written in an active voice, avoiding third-person perspective .Interconnect the trust-building elements contextually and creatively to enhance the reading flow, making it clear what the impact is on audience. While prompts may mention terms like Stability, Development, Competence, Relationship, Benefit, or Vision, do not include words like "trust","cutting-edge","beacon,"beacon of hope"and "realm" in any of the output. Trust word can be used like here are these eg Development trust builders but in the copy .**
 
350
  ### MANDATORY VERIFICATION CHECKLIST:
351
  Before submitting **any content**, ensure that each piece includes:
352
  1. **Specific Details**:
@@ -363,11 +620,13 @@ Before submitting **any content**, ensure that each piece includes:
363
  - "This [specific benefit] for [specific audience]"
364
  - **Example**: "This reduces wait times by 47% for patients seeking emergency care."
365
  3. *Give [sources] next to each trust building point and heuristics and creative techniques with every copy application*.
 
366
  *SOURCE LINK REQUIREMENTS*
367
  1. **Each source link must**:
368
  - Be **working and clickable**.
369
  - Be **no older than 2 years** unless historically significant.
370
  2. Refer knowledge base for description, guiding principles, question to consider and examples for relevant trustbucket then *search on google* and then give relevant trustbuilders.
 
371
  ##SPECIFICITY ENFORCEMENT
372
  Replace vague phrases with specific details:
373
  - ❌ "many" → ✅ exact number.
@@ -377,6 +636,7 @@ Replace vague phrases with specific details:
377
  - ��� "industry leader" → ✅ "ranked #1 in customer satisfaction by J.D. Power in 2023".
378
  - ❌ "significant impact" → ✅ "47% reduction in processing time".
379
  - ❌ "team of experts" → ✅ "157 certified professionals led by Dr. Sarah Chen".
 
380
  ###ERROR CHECKING
381
  Before submitting, verify and fix:
382
  **When query is to find trust builders never mention heuristic and creative techniques**
@@ -387,6 +647,7 @@ Before submitting, verify and fix:
387
  5. **No missing specific details** from the mandatory checklist.
388
  6. **No prohibited terms included in the copy. For searching it can be used.**.
389
  7. ** DONOT INCLUDE heuristic and creative techniques in Trustbuilder queries**
 
390
  ###CRITICAL MANDATORY INSTRUCTIONS
391
  - **Avoid Prohibited Terms**:
392
  - Do **not** mention "trust," "trust buckets," or any category names like "Development," "Stability," "Competence," "Relationship," "Vision" in the final copy.
@@ -407,7 +668,9 @@ Before submitting, verify and fix:
407
  -Limit to 3-5 items in each category.
408
  Note: When including heuristics and creative techniques, use the single line structure “Heuristics: examples” and “Creative Techniques: examples” with no extra details.
409
  - If the query is about trust builders , do not include heuristics or creative techniques,List of TrustBuilders Used.
 
410
  ### CONTENT TYPES AND FORMATS
 
411
  #### 1. Annual report article / article
412
  - **Introduction**: Start with "Here is a draft of your [Annual Report/Article]. Feel free to suggest further refinements."
413
  - **Structure**:
@@ -428,6 +691,7 @@ Before submitting, verify and fix:
428
  - **Important Notes**:
429
  - **Strictly search and provide accurate source links always**.
430
  - Include heuristics and creative techniques if requested.
 
431
  #### 2. Social Media Posts
432
  - **Introduction Line**: Start with "Here is a draft of your social media post. Feel free to suggest further refinements."
433
  - **Content**:
@@ -481,6 +745,7 @@ Before submitting, verify and fix:
481
  -Limit to 3-5 items in each category.
482
  Note: When including heuristics and creative techniques, use the structure “Heuristics: examples” and “Creative Techniques: examples” with no extra details.
483
  - **Word Count**: Follow any specified word count for the main body. Do not count sub-heading sections in the word count limit.
 
484
  ### 5.Trust-Based Queries:**
485
  Be over specific with numbers,names,dollars, programs ,awards and action.
486
  - When a query seeks a specific number of trust builders (e.g., "5 trust builders"), the AI should:
@@ -502,9 +767,11 @@ Note: When including heuristics and creative techniques, use the structure “He
502
  - **People** (5 points)
503
  - **Offers/Services** (5 points)
504
  - **Important Specificity:** Always include **names**, **numbers** (e.g., $ amounts and years), **programs**, **strategies**, **places**, **awards**, and **actions** by searching on google to add credibility and depth to the content. Ensure that trust-building points are detailed and specific.
 
505
  - **For Specific Categories:**
506
  - When a query asks for a specific category (e.g., "Development trust builders"), find 15 trust-building points that are specific with relevant names, numbers like $ amounts and years, programs, strategies, places, awards, and actions specifically for that category.
507
  - Categorize these points into Organization, People, and Offers/Services (with 5 points for each category).
 
508
  - **Format:**
509
  - **Introduction Line:** Start with "Here are TrustBuilders® for [Selected Categories] at [Organization Name]. Let me know if you want to refine the results or find more."
510
  - **Categories:**
@@ -528,6 +795,7 @@ Note: When including heuristics and creative techniques, use the structure “He
528
  - [Trust-Building Point 15] - [Source](#)
529
  - Ensure each selected category contains 15 trust-building points, categorized as specified.
530
  - Provide bullet points under each section with relevant accurate source link.
 
531
  **Important Notes:**
532
  - Strictly search and provide accurate source links always.
533
  - **No Subheadings or Labels:** Under each main category, list the trust-building points directly as bullet points or numbered lists **without any additional subheadings, labels, descriptors, phrases, or words before the points**.
@@ -544,18 +812,17 @@ Note: When including heuristics and creative techniques, use the structure “He
544
  - **Example of Correct Format**:
545
  **Organization**
546
  - In **2023**, World Vision invested **$150 million** in sustainable agriculture programs across **35 countries**, impacting over **2 million** farmers.This improves food security for vulnerable communities.- [Source](#)
 
547
  ### 6. LinkedIn Profile
548
  - If requested, generate a LinkedIn profile in a professional manner.
549
  - **Avoid prohibited terms** and **flowery language**.
 
550
  ### GENERAL QUERIES
551
  - Donot use knowledge base for non-trust content.Give quick output according to above given guidance.
552
  - **Audience Impact**: Always clarify what the information means to the audience.
553
 
554
- """
555
-
556
-
557
-
558
 
 
559
 
560
  prompt_template = ChatPromptTemplate.from_messages([
561
  ("system", prompt_message),
@@ -565,7 +832,7 @@ prompt_template = ChatPromptTemplate.from_messages([
565
  ])
566
 
567
  # Create Langchain Agent
568
- llm = ChatOpenAI(model="gpt-4o", temperature=0.5)
569
  llm_with_tools = llm.bind_tools(tools)
570
 
571
  # Define the agent pipeline
@@ -684,7 +951,69 @@ if not st.session_state.get("chat_started", False):
684
  </div>
685
  <div style="height: 50px;"></div> <!-- Adds a gap of 50px after the section containers -->
686
  """, unsafe_allow_html=True)
687
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
688
 
689
  trust_tips = [
690
  "What I don’t know I can’t trust you for. Make sure you know all your great TrustBuilders® and use them over time.",
@@ -742,6 +1071,7 @@ def add_dot_typing_animation():
742
  display: flex;
743
  align-items: center;
744
  }
 
745
  .dot {
746
  height: 10px;
747
  width: 10px;
@@ -751,12 +1081,15 @@ def add_dot_typing_animation():
751
  display: inline-block;
752
  animation: dot-blink 1.5s infinite ease-in-out;
753
  }
 
754
  .dot:nth-child(2) {
755
  animation-delay: 0.2s;
756
  }
 
757
  .dot:nth-child(3) {
758
  animation-delay: 0.4s;
759
  }
 
760
  @keyframes dot-blink {
761
  0% {
762
  opacity: 0.3;
@@ -782,76 +1115,210 @@ def display_typing_indicator():
782
  <span class="dot"></span>
783
  </div>
784
  """
 
785
  st.markdown(dot_typing_html, unsafe_allow_html=True)
 
 
786
 
787
- prompt = st.chat_input("")
788
- if prompt :
789
-
790
- st.session_state["chat_started"] = True
791
- # Add user message to chat history
792
- st.session_state.chat_history.append({"role": "user", "content": prompt})
793
-
794
 
795
- # Display user message
796
- with st.chat_message("user"):
797
- st.markdown(prompt)
798
- response_placeholder = st.empty()
799
-
800
- # Generate AI response
801
- with response_placeholder:
802
- with st.chat_message("assistant"):
803
- add_dot_typing_animation() # Adds the CSS for the typing animation
804
- display_typing_indicator()
805
-
 
 
806
 
807
- full_response = ""
808
-
809
- try:
810
- # Generate response using the agent executor
811
- output = agent_executor.invoke({
812
 
813
- "input": f" {prompt} Be in natural tone.Sources should be accurate.Avoid AI jargons.DONOT USE use words that end with '-ing' for headlines and subheadlines when asked to write a article,blog,newsletter.",
814
-
815
-
816
- "chat_history": st.session_state.chat_history
817
- })
818
- full_response = output["output"]
819
- #full_response= replace_terms(full_response)
820
-
821
- cleaned_text = clean_text(full_response)
822
- cleaned_text = re.sub(r'<[^>]*>', '', cleaned_text)
823
-
824
-
825
-
826
- #cleaned_text = re.sub(r'</span>', '', cleaned_text)
827
- #cleaned_text = re.sub(r'<span[^>]*>', '', cleaned_text)
828
- # Display the response
829
-
830
- trust_tip, suggestion = get_trust_tip_and_suggestion()
831
-
832
- #combined_text = f"{cleaned_text}\n\n---\n\n**Trust Tip**: {trust_tip}\n\n**Suggestion**: {suggestion}"
833
- combined_text = f"{cleaned_text}\n\n---\n\n**Trust Tip**: {trust_tip}\n\n**Suggestion**: {suggestion}"
834
-
835
- #st.markdown(combined_text,unsafe_allow_html=True)
836
-
837
- #seprtor= st.markdown("---") # Add a separator
838
- #t_tip= st.markdown(f"**Trust Tip**: {trust_tip}")
839
- #s_sug- st.markdown(f"**Suggestion**: {suggestion}")
840
- with response_placeholder:
841
- with st.chat_message("assistant"):
842
- st.markdown(combined_text, unsafe_allow_html=True)
843
 
 
 
 
 
 
 
 
 
844
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
845
 
846
-
847
-
848
-
849
- except Exception as e:
850
- logger.error(f"Error generating response: {e}")
851
- full_response = "I apologize, but an error occurred while generating the response. Please try again."
852
- st.write(full_response)
853
-
854
- # Add AI response to chat history
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
855
 
856
- st.session_state.chat_history.append({"role": "assistant", "content": cleaned_text})
857
- copy_to_clipboard(cleaned_text)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import logging
2
  import os
3
+ import streamlit as st
4
  from dotenv import load_dotenv
5
  import openai
6
  from langchain_openai import ChatOpenAI
 
14
  from langchain_community.document_loaders import TextLoader
15
  from langchain_text_splitters import CharacterTextSplitter
16
  import serpapi
17
+ import requests
18
  import streamlit.components.v1 as components
19
  import smtplib
20
  from email.mime.multipart import MIMEMultipart
 
27
  from email.mime.multipart import MIMEMultipart
28
  from email.mime.text import MIMEText
29
  from markdownify import markdownify
30
+ import chargebee
31
+ import pyrebase
32
+ import streamlit.components.v1 as components
33
+ import time
34
+ import warnings
35
+ from streamlit.components.v1 import html
36
+ from langchain.docstore.document import Document
37
+ import firebase_admin
38
+ import uuid
39
+ import json
40
+ import io
41
+ from firebase_admin import credentials, firestore
42
+ import base64
43
+ from pdfminer.high_level import extract_text # Import for PDF text extraction
44
+
45
+ st.set_page_config(layout="wide")
46
+ import logging
47
+ import asyncio
48
+ import re
49
+ # Set up logging to suppress Streamlit warnings about experimental functions
50
+ logging.getLogger('streamlit').setLevel(logging.ERROR)
51
+
52
+
53
+
54
 
55
  # Initialize logging and load environment variables
56
  logging.basicConfig(level=logging.INFO)
57
  logger = logging.getLogger(__name__)
58
  load_dotenv()
59
 
60
+ chargebee.configure(site="mextconsulting", api_key="live_dBLXn8yG5dFcuIgU5Szebj2KfTcdt4hjpf")
61
+
62
+ # Firebase Configuration
63
+ firebase_config = {
64
+ "apiKey": "AIzaSyAWiaqrduoG7fzmJxBVnVg9nCC4EoEnwfY",
65
+ "authDomain": "trustai-3e7a2.firebaseapp.com",
66
+ "databaseURL": "https://trustai-3e7a2-default-rtdb.firebaseio.com",
67
+ "projectId": "trustai-3e7a2",
68
+ "storageBucket": "trustai-3e7a2.appspot.com",
69
+ "messagingSenderId": "964339831031",
70
+ "appId": "1:964339831031:web:66d21ceea68ab03f1043f2",
71
+ "measurementId": "G-ZMLZQZMHK2"
72
+ }
73
+ # Initialize Firebase
74
+ firebase = pyrebase.initialize_app(firebase_config)
75
+ db = firebase.database()
76
+ storage = firebase.storage()
77
+
78
+
79
+ def convert_pdf_to_md(file):
80
+ """
81
+ Convert a PDF file to Markdown.
82
+ """
83
+ try:
84
+ text = extract_text(file)
85
+ return f"# PDF Document\n\n{text}"
86
+ except Exception as e:
87
+ logger.error(f"Error converting PDF to MD: {e}")
88
+ return ""
89
+
90
+ def convert_docx_to_md(file):
91
+ """
92
+ Convert a Word (DOCX) file to Markdown.
93
+ """
94
+ try:
95
+ doc = Document(file)
96
+ full_text = '\n'.join([para.text for para in doc.paragraphs])
97
+ return f"# Word Document\n\n{full_text}"
98
+ except Exception as e:
99
+ logger.error(f"Error converting DOCX to MD: {e}")
100
+ return ""
101
+
102
+ def convert_txt_to_md(file):
103
+ """
104
+ Convert a TXT file to Markdown.
105
+ """
106
+ try:
107
+ text = file.read().decode("utf-8")
108
+ return f"# Text Document\n\n{text}"
109
+ except Exception as e:
110
+ logger.error(f"Error converting TXT to MD: {e}")
111
+ return ""
112
 
113
+ def convert_file_to_md(file):
114
+ """
115
+ Detect file type and convert to Markdown accordingly.
116
+ """
117
+ if file.type == "application/pdf":
118
+ return convert_pdf_to_md(file)
119
+ elif file.type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
120
+ return convert_docx_to_md(file)
121
+ elif file.type == "text/plain":
122
+ return convert_txt_to_md(file)
123
+ else:
124
+ st.sidebar.warning(f"Unsupported file type: {file.type}")
125
+ return ""
126
+
127
+ def merge_markdown_contents(contents):
128
+ """
129
+ Merge multiple Markdown contents into a single Markdown string.
130
+ """
131
+ merged_content = "\n\n---\n\n".join(contents)
132
+ return merged_content
133
 
134
+ def upload_to_firebase(user_id, merged_md_content):
135
+ """
136
+ Upload the merged Markdown content to Firebase Storage.
137
+ Returns the public URL of the uploaded file.
138
+ """
139
+ try:
140
+ file_path = f"knowledge_bases/{user_id}/knowledge_base.md"
141
+ # Upload the content as bytes
142
+ storage.child(file_path).put(io.BytesIO(merged_md_content.encode('utf-8')), content_type="text/markdown")
143
+ # Get the download URL
144
+ public_url = storage.child(file_path).get_url(None)
145
+ return public_url
146
+ except Exception as e:
147
+ logger.error(f"Error uploading to Firebase Storage: {e}")
148
+ st.sidebar.error(f"Error uploading files: {e}")
149
+ return None
150
 
151
  # Define and validate API keys
152
  openai_api_key = os.getenv("OPENAI_API_KEY")
 
178
  st.session_state.used_trust_tips = set()
179
  if 'used_suggestions' not in st.session_state:
180
  st.session_state.used_suggestions = set()
181
+
182
+
183
+ backend_url = "https://backend-web-05122eab4e09.herokuapp.com"
184
+ # Suppress Streamlit deprecation and warning messages
185
+
186
  def copy_to_clipboard(text):
187
  """Creates a button to copy text to clipboard."""
188
  escaped_text = text.replace('\n', '\\n').replace('"', '\\"')
 
240
  </script>
241
  """
242
  components.html(copy_icon_html, height=60)
243
+
 
244
  def send_feedback_via_email(name, email, feedback):
245
  """Sends an email with feedback details."""
246
  smtp_server = 'smtp.office365.com'
 
318
  return cleaned_text
319
 
320
 
321
+
322
 
323
 
324
  def get_trust_tip_and_suggestion():
 
328
 
329
 
330
 
331
+ def load_main_data_source():
332
+ try:
333
+ with open("./data_source/time_to_rethink_trust_book.md", "r") as f:
334
+ main_content = f.read()
335
+
336
+ # Split main content into chunks
337
+ text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
338
+ main_texts = text_splitter.split_text(main_content)
339
 
340
+ # Create Document objects for the main data source
341
+ main_documents = [Document(page_content=text) for text in main_texts]
342
+ return main_documents
343
+ except Exception as e:
344
+ st.error(f"Error loading main data source: {e}")
345
+ return []
346
 
347
+ def combine_data_sources():
348
+ main_data_source = load_main_data_source()
349
+ user_data_source = load_user_data_source(st.session_state["wix_user_id"])
350
+
351
+ trustbuilders = [Document(page_content=tb["message"]) for tb in st.session_state.get("trustbuilders", {}).values()]
352
+ brand_tonalities = [Document(page_content=bt["message"]) for bt in st.session_state.get("brand_tonality", {}).values()]
353
 
354
+ return main_data_source + user_data_source + trustbuilders + brand_tonalities
355
+
356
+
357
+ def refresh_faiss_index():
358
+ combined_sources = combine_data_sources()
359
+ if combined_sources:
360
+ embeddings = OpenAIEmbeddings()
361
+ db_faiss = FAISS.from_documents(combined_sources, embeddings)
362
+ st.session_state["faiss_db"] = db_faiss
363
+
364
+ def load_user_data_source(user_id):
365
+ """
366
+ Load user-uploaded data source from Firebase.
367
+ """
368
+ try:
369
+ file_path = f"knowledge_bases/{user_id}/knowledge_base.md"
370
+ storage_url = storage.child(file_path).get_url(None)
371
+ response = requests.get(storage_url)
372
+
373
+ if response.status_code == 200:
374
+ user_content = response.text
375
+ st.session_state["user_data_source"] = user_content
376
+ return [Document(page_content=user_content)]
377
+ else:
378
+ return []
379
+ except Exception as e:
380
+ st.error(f"Error loading user data source: {e}")
381
+ return []
382
+
383
+
384
+
385
+
386
+ def store_brand_tonality(user_id, message):
387
+ try:
388
+ tonality_id = str(uuid.uuid4())
389
+ db.child("users").child(user_id).child("brandTonality").child(tonality_id).set({"message": message})
390
+
391
+ # Update st.session_state for instant display in sidebar
392
+ if "brand_tonality" not in st.session_state:
393
+ st.session_state["brand_tonality"] = {}
394
+ st.session_state["brand_tonality"][tonality_id] = {"message": message}
395
+ display_save_confirmation("Brand Tonality")
396
+ except Exception as e:
397
+ st.error(f"Error saving Brand Tonality: {e}")
398
+
399
+ def store_trustbuilder(user_id, message):
400
+ try:
401
+ trustbuilder_id = str(uuid.uuid4())
402
+ db.child("users").child(user_id).child("trustBuilders").child(trustbuilder_id).set({"message": message})
403
+
404
+ # Update st.session_state for instant display in sidebar
405
+ if "trustbuilders" not in st.session_state:
406
+ st.session_state["trustbuilders"] = {}
407
+ st.session_state["trustbuilders"][trustbuilder_id] = {"message": message}
408
+ display_save_confirmation("TrustBuilder")
409
+ except Exception as e:
410
+ st.error(f"Error saving TrustBuilder: {e}")
411
+
412
+ def load_user_content(user_id):
413
+ """Load TrustBuilders and Brand Tonalities from Firebase."""
414
+ try:
415
+ trustbuilders = db.child("users").child(user_id).child("trustBuilders").get()
416
+ brand_tonalities = db.child("users").child(user_id).child("brandTonality").get()
417
+ st.session_state["TrustBuilders"] = [item.val()["content"] for item in trustbuilders.each()] if trustbuilders.each() else []
418
+ st.session_state["BrandTonality"] = [item.val()["content"] for item in brand_tonalities.each()] if brand_tonalities.each() else []
419
+ except Exception as e:
420
+ st.error(f"Error loading saved content: {e}")
421
+
422
+ def save_content(user_id, content, content_type):
423
+ try:
424
+ entry_id = str(uuid.uuid4())
425
+ db.child("users").child(user_id).child(content_type).child(entry_id).set({"message": content})
426
+
427
+ # Update session state directly after saving to avoid duplicates
428
+ st.session_state[content_type.lower()][entry_id] = {"message": content}
429
+ display_save_confirmation(content_type)
430
+ except Exception as e:
431
+ logger.error(f"Error saving {content_type}: {e}")
432
+ st.error(f"Could not save {content_type}. Please try again.")
433
+
434
+ def display_saved_trustbuilders():
435
+ """
436
+ Display saved TrustBuilders and Brand Tonality entries with download and delete options.
437
+ """
438
+ st.sidebar.subheader("Saved TrustBuilders")
439
+ trustbuilders = st.session_state.get("trustbuilders", {})
440
+ for trustbuilder_id, trustbuilder_data in trustbuilders.items():
441
+ st.sidebar.markdown(f"- {trustbuilder_data['message'][:50]}...")
442
+ st.sidebar.markdown(download_link(trustbuilder_data["message"], f"TrustBuilder_{trustbuilder_id}.md"), unsafe_allow_html=True)
443
+ if st.sidebar.button("❌", key=f"del_tb_{trustbuilder_id}"):
444
+ delete_entry("trustBuilders", trustbuilder_id, "trustbuilders")
445
+ st.rerun()
446
+
447
+ st.sidebar.subheader("Saved Brand Tonality")
448
+ brand_tonality = st.session_state.get("brand_tonality", {})
449
+ for tonality_id, tonality_data in brand_tonality.items():
450
+ st.sidebar.markdown(f"- {tonality_data['message'][:50]}...")
451
+ st.sidebar.markdown(download_link(tonality_data["message"], f"BrandTonality_{tonality_id}.md"), unsafe_allow_html=True)
452
+ if st.sidebar.button("❌", key=f"del_bt_{tonality_id}"):
453
+ delete_entry("brandTonality", tonality_id, "brand_tonality")
454
+ st.rerun()
455
+
456
+
457
+ def download_link(content, filename):
458
+ """
459
+ Create a download link for content.
460
+ """
461
+ b64 = base64.b64encode(content.encode()).decode()
462
+ return f'<a href="data:text/plain;base64,{b64}" download="{filename}">Download</a>'
463
+
464
+
465
+
466
+ def side():
467
+ with st.sidebar:
468
+ st.image("Trust Logic_Wheel_RGB_Standard.png")
469
  st.header("Let's create something great.")
470
+
471
+ with st.sidebar.expander("Explore", expanded=False):
472
+ st.markdown(
473
+ "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. Trustifier.ai®, 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."
474
+ )
475
+ st.markdown(
476
+ """
477
  <style>
478
  .stability { color: rgb(7, 55, 99); font-size: 24px; font-weight: bold; }
479
  .development { color: rgb(241, 194, 50); font-size: 24px; font-weight: bold; }
 
482
  .vision { color: rgb(255, 153, 0); font-size: 24px; font-weight: bold; }
483
  .competence { color: rgb(111, 168, 220); font-size: 24px; font-weight: bold; }
484
  </style>
485
+
486
  <h3 class="stability">Stability Trust:</h3>
487
  <p>Why can I trust you to have built a strong and stable foundation?</p>
488
+
489
  <h3 class="development">Development Trust:</h3>
490
  <p>Why can I trust you to develop well in the future?</p>
491
+
492
  <h3 class="relationship">Relationship Trust:</h3>
493
  <p>What appealing relationship qualities can I trust you for?</p>
494
+
495
  <h3 class="benefit">Benefit Trust:</h3>
496
  <p>What benefits can I trust you for?</p>
497
+
498
  <h3 class="vision">Vision Trust:</h3>
499
  <p>What Vision and Values can I trust you for?</p>
500
+
501
  <h3 class="competence">Competence Trust:</h3>
502
  <p>What competencies can I trust you for?</p>
503
+ """, unsafe_allow_html=True
504
+ )
505
+ st.markdown("For detailed descriptions, visit [Academy](https://www.trustifier.ai/account/academy)")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
 
507
+ st.header("Upload Data source")
508
+
509
+ with st.form(key="upload_form"):
510
+ uploaded_files = st.file_uploader("Upload PDF, DOCX, or TXT files", type=["pdf", "docx", "txt"], accept_multiple_files=True)
511
+ submit_button = st.form_submit_button("Upload")
512
+
513
+ if submit_button and uploaded_files:
514
+ md_contents = [convert_file_to_md(file) for file in uploaded_files if convert_file_to_md(file)]
515
+ if md_contents:
516
+ merged_md = merge_markdown_contents(md_contents)
517
+ upload_url = upload_to_firebase(st.session_state["wix_user_id"], merged_md)
518
+ if upload_url:
519
+ st.success("Files uploaded and processed successfully!")
520
+ st.markdown(f"[View your uploaded knowledge base here]({upload_url})", unsafe_allow_html=True)
521
+ refresh_faiss_index()
522
+ # Save Custom Content section
523
+ st.header("Save Custom Content")
524
+ custom_content = st.text_area("Enter content to save")
525
+
526
+ if st.button("Save as Brand Tonality"):
527
+ save_content(st.session_state["wix_user_id"], custom_content, "BrandTonality")
528
+ display_save_confirmation("Brand Tonality")
529
+ if st.button("Save as TrustBuilder"):
530
+ save_content(st.session_state["wix_user_id"], custom_content, "TrustBuilder")
531
+ display_save_confirmation("TrustBuilder")
532
 
533
 
534
 
535
  side()
536
  # Load knowledge base
 
 
 
 
 
 
 
 
 
 
537
 
 
538
 
539
+ # Initialize embeddings and FAISS index only when wix_user_id is set
540
+
541
+ if st.session_state.get("wix_user_id") and "faiss_db" not in st.session_state:
542
+ refresh_faiss_index()
543
+
544
 
545
  # Define search functions
546
  def search_knowledge_base(query):
547
+ """
548
+ Searches the FAISS index using the provided query.
549
+ Returns the most relevant documents based on the query.
550
+ """
551
+ if "faiss_db" not in st.session_state:
552
+ st.error("FAISS database is not initialized.")
553
+ return []
554
+
555
+ # Retrieve the top 5 most relevant documents
556
+ retrieved_docs = st.session_state["faiss_db"].similarity_search(query, k=5)
557
+ return retrieved_docs
558
+
559
  def google_search(query):
560
  try:
561
  search_client = serpapi.Client(api_key=serper_api_key)
 
603
 
604
  prompt_message = f"""
605
  **You are an expert copywriter specializing in creating highly creative marketing content in natural tone that integrates **Trust Builders** into various content formats for any organization. Your goal is to produce compelling, factual,and well-structured material that is concise and based on the knowledgebase, adhering to the following guidelines.The content should be written in an active voice, avoiding third-person perspective .Interconnect the trust-building elements contextually and creatively to enhance the reading flow, making it clear what the impact is on audience. While prompts may mention terms like Stability, Development, Competence, Relationship, Benefit, or Vision, do not include words like "trust","cutting-edge","beacon,"beacon of hope"and "realm" in any of the output. Trust word can be used like here are these eg Development trust builders but in the copy .**
606
+
607
  ### MANDATORY VERIFICATION CHECKLIST:
608
  Before submitting **any content**, ensure that each piece includes:
609
  1. **Specific Details**:
 
620
  - "This [specific benefit] for [specific audience]"
621
  - **Example**: "This reduces wait times by 47% for patients seeking emergency care."
622
  3. *Give [sources] next to each trust building point and heuristics and creative techniques with every copy application*.
623
+
624
  *SOURCE LINK REQUIREMENTS*
625
  1. **Each source link must**:
626
  - Be **working and clickable**.
627
  - Be **no older than 2 years** unless historically significant.
628
  2. Refer knowledge base for description, guiding principles, question to consider and examples for relevant trustbucket then *search on google* and then give relevant trustbuilders.
629
+
630
  ##SPECIFICITY ENFORCEMENT
631
  Replace vague phrases with specific details:
632
  - ❌ "many" → ✅ exact number.
 
636
  - ��� "industry leader" → ✅ "ranked #1 in customer satisfaction by J.D. Power in 2023".
637
  - ❌ "significant impact" → ✅ "47% reduction in processing time".
638
  - ❌ "team of experts" → ✅ "157 certified professionals led by Dr. Sarah Chen".
639
+
640
  ###ERROR CHECKING
641
  Before submitting, verify and fix:
642
  **When query is to find trust builders never mention heuristic and creative techniques**
 
647
  5. **No missing specific details** from the mandatory checklist.
648
  6. **No prohibited terms included in the copy. For searching it can be used.**.
649
  7. ** DONOT INCLUDE heuristic and creative techniques in Trustbuilder queries**
650
+
651
  ###CRITICAL MANDATORY INSTRUCTIONS
652
  - **Avoid Prohibited Terms**:
653
  - Do **not** mention "trust," "trust buckets," or any category names like "Development," "Stability," "Competence," "Relationship," "Vision" in the final copy.
 
668
  -Limit to 3-5 items in each category.
669
  Note: When including heuristics and creative techniques, use the single line structure “Heuristics: examples” and “Creative Techniques: examples” with no extra details.
670
  - If the query is about trust builders , do not include heuristics or creative techniques,List of TrustBuilders Used.
671
+
672
  ### CONTENT TYPES AND FORMATS
673
+
674
  #### 1. Annual report article / article
675
  - **Introduction**: Start with "Here is a draft of your [Annual Report/Article]. Feel free to suggest further refinements."
676
  - **Structure**:
 
691
  - **Important Notes**:
692
  - **Strictly search and provide accurate source links always**.
693
  - Include heuristics and creative techniques if requested.
694
+
695
  #### 2. Social Media Posts
696
  - **Introduction Line**: Start with "Here is a draft of your social media post. Feel free to suggest further refinements."
697
  - **Content**:
 
745
  -Limit to 3-5 items in each category.
746
  Note: When including heuristics and creative techniques, use the structure “Heuristics: examples” and “Creative Techniques: examples” with no extra details.
747
  - **Word Count**: Follow any specified word count for the main body. Do not count sub-heading sections in the word count limit.
748
+
749
  ### 5.Trust-Based Queries:**
750
  Be over specific with numbers,names,dollars, programs ,awards and action.
751
  - When a query seeks a specific number of trust builders (e.g., "5 trust builders"), the AI should:
 
767
  - **People** (5 points)
768
  - **Offers/Services** (5 points)
769
  - **Important Specificity:** Always include **names**, **numbers** (e.g., $ amounts and years), **programs**, **strategies**, **places**, **awards**, and **actions** by searching on google to add credibility and depth to the content. Ensure that trust-building points are detailed and specific.
770
+
771
  - **For Specific Categories:**
772
  - When a query asks for a specific category (e.g., "Development trust builders"), find 15 trust-building points that are specific with relevant names, numbers like $ amounts and years, programs, strategies, places, awards, and actions specifically for that category.
773
  - Categorize these points into Organization, People, and Offers/Services (with 5 points for each category).
774
+
775
  - **Format:**
776
  - **Introduction Line:** Start with "Here are TrustBuilders® for [Selected Categories] at [Organization Name]. Let me know if you want to refine the results or find more."
777
  - **Categories:**
 
795
  - [Trust-Building Point 15] - [Source](#)
796
  - Ensure each selected category contains 15 trust-building points, categorized as specified.
797
  - Provide bullet points under each section with relevant accurate source link.
798
+
799
  **Important Notes:**
800
  - Strictly search and provide accurate source links always.
801
  - **No Subheadings or Labels:** Under each main category, list the trust-building points directly as bullet points or numbered lists **without any additional subheadings, labels, descriptors, phrases, or words before the points**.
 
812
  - **Example of Correct Format**:
813
  **Organization**
814
  - In **2023**, World Vision invested **$150 million** in sustainable agriculture programs across **35 countries**, impacting over **2 million** farmers.This improves food security for vulnerable communities.- [Source](#)
815
+
816
  ### 6. LinkedIn Profile
817
  - If requested, generate a LinkedIn profile in a professional manner.
818
  - **Avoid prohibited terms** and **flowery language**.
819
+
820
  ### GENERAL QUERIES
821
  - Donot use knowledge base for non-trust content.Give quick output according to above given guidance.
822
  - **Audience Impact**: Always clarify what the information means to the audience.
823
 
 
 
 
 
824
 
825
+ """
826
 
827
  prompt_template = ChatPromptTemplate.from_messages([
828
  ("system", prompt_message),
 
832
  ])
833
 
834
  # Create Langchain Agent
835
+ llm = ChatOpenAI(model="gpt-4o", temperature=0.6)
836
  llm_with_tools = llm.bind_tools(tools)
837
 
838
  # Define the agent pipeline
 
951
  </div>
952
  <div style="height: 50px;"></div> <!-- Adds a gap of 50px after the section containers -->
953
  """, unsafe_allow_html=True)
954
+
955
+ hide_specific_warning = """
956
+ <script>
957
+ document.addEventListener('DOMContentLoaded', function() {
958
+ const alerts = window.parent.document.querySelectorAll('div[data-testid="stAlert"]');
959
+ alerts.forEach(function(alert) {
960
+ if (alert.innerText.includes('Please replace st.experimental_get_query_params with st.query_params')) {
961
+ alert.style.display = 'none'; // Hide the warning
962
+ alert.style.visibility = 'hidden'; // Make it invisible
963
+ alert.style.height = '0px'; // Set height to zero to remove space
964
+ alert.style.margin = '0px'; // Set margin to zero
965
+ alert.style.padding = '0px'; // Set padding to zero
966
+ }
967
+ });
968
+ });
969
+ </script>
970
+ """
971
+
972
+
973
+ # Embed the JavaScript in your Streamlit app
974
+ components.html(hide_specific_warning, height=0, scrolling=False)
975
+
976
+ query_params = st.experimental_get_query_params()
977
+ wix_user_id = query_params.get('wix_user_id', [None])[0]
978
+ email = query_params.get('email', [None])[0]
979
+
980
+ # Session state to track user login and message usage
981
+ if "wix_user_id" not in st.session_state:
982
+ st.session_state["wix_user_id"] = wix_user_id
983
+ if "email" not in st.session_state:
984
+ st.session_state["email"] = email
985
+ if "message_limit" not in st.session_state:
986
+ st.session_state["message_limit"] = 0
987
+ if "used_messages" not in st.session_state:
988
+ st.session_state["used_messages"] = 0
989
+
990
+
991
+ def receive_wix_message():
992
+ components.html(
993
+ """
994
+ <script>
995
+ window.addEventListener('message', function(event) {
996
+ const data = event.data;
997
+ if (data.wixUserId && data.email) {
998
+ window.parent.postMessage({
999
+ 'wix_user_id': data.wixUserId,
1000
+ 'email': data.email
1001
+ }, "*");
1002
+
1003
+ // Send message back to Streamlit
1004
+ window.parent.postMessage({
1005
+ wix_user_id: data.wixUserId,
1006
+ email: data.email
1007
+ }, "*");
1008
+ }
1009
+ });
1010
+ </script>
1011
+ """,
1012
+ height=0
1013
+ )
1014
+
1015
+ # Calling this function to initialize listening for Wix messages
1016
+ receive_wix_message()
1017
 
1018
  trust_tips = [
1019
  "What I don’t know I can’t trust you for. Make sure you know all your great TrustBuilders® and use them over time.",
 
1071
  display: flex;
1072
  align-items: center;
1073
  }
1074
+
1075
  .dot {
1076
  height: 10px;
1077
  width: 10px;
 
1081
  display: inline-block;
1082
  animation: dot-blink 1.5s infinite ease-in-out;
1083
  }
1084
+
1085
  .dot:nth-child(2) {
1086
  animation-delay: 0.2s;
1087
  }
1088
+
1089
  .dot:nth-child(3) {
1090
  animation-delay: 0.4s;
1091
  }
1092
+
1093
  @keyframes dot-blink {
1094
  0% {
1095
  opacity: 0.3;
 
1115
  <span class="dot"></span>
1116
  </div>
1117
  """
1118
+
1119
  st.markdown(dot_typing_html, unsafe_allow_html=True)
1120
+ def display_save_confirmation(type_saved):
1121
+ st.info(f"Content successfully saved as **{type_saved}**!")
1122
 
 
 
 
 
 
 
 
1123
 
1124
+ def extract_name(email):
1125
+ return email.split('@')[0].capitalize()
1126
+
1127
+ if "trustbuilders" not in st.session_state:
1128
+ st.session_state["trustbuilders"] = {}
1129
+ if "brand_tonality" not in st.session_state:
1130
+ st.session_state["brand_tonality"] = {}
1131
+
1132
+ # Load saved entries upon user login
1133
+ def retrieve_user_data(user_id):
1134
+ try:
1135
+ trustbuilders = db.child("users").child(user_id).child("trustBuilders").get().val() or {}
1136
+ brand_tonality = db.child("users").child(user_id).child("brandTonality").get().val() or {}
1137
 
1138
+ # Set retrieved data into session state
1139
+ st.session_state["trustbuilders"] = trustbuilders
1140
+ st.session_state["brand_tonality"] = brand_tonality
1141
+ except Exception as e:
1142
+ st.error("Error loading saved entries. Please try again later.")
1143
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1144
 
1145
+
1146
+
1147
+
1148
+
1149
+
1150
+ # Function to handle queries about saved TrustBuilders or Brand Tonality
1151
+ def handle_memory_queries(prompt):
1152
+ prompt = prompt.lower().strip()
1153
 
1154
+ # Save as TrustBuilder, removing the phrase from the content
1155
+ if "save this as trustbuilder" in prompt:
1156
+ content_to_save = prompt.replace("save this as trustbuilder", "").strip()
1157
+ if content_to_save: # Only save if there's actual content
1158
+ store_trustbuilder(st.session_state["wix_user_id"], content_to_save)
1159
+ return "TrustBuilder saved successfully!"
1160
+ else:
1161
+ return "Please provide content to save as TrustBuilder."
1162
+
1163
+ # Save as Brand Tonality, removing the phrase from the content
1164
+ elif "save this as brand tonality" in prompt:
1165
+ content_to_save = prompt.replace("save this as brand tonality", "").strip()
1166
+ if content_to_save: # Only save if there's actual content
1167
+ store_brand_tonality(st.session_state["wix_user_id"], content_to_save)
1168
+ return "Brand Tonality saved successfully!"
1169
+ else:
1170
+ return "Please provide content to save as Brand Tonality."
1171
+
1172
+ # Retrieve saved TrustBuilders
1173
+ elif "show my saved trustbuilders" in prompt or "find my saved trustbuilders" in prompt:
1174
+ if st.session_state.get("trustbuilders"):
1175
+ return "\n".join([f"- {entry['message']}" for entry in st.session_state["trustbuilders"].values()])
1176
+ else:
1177
+ return "You haven't saved any TrustBuilders yet."
1178
+
1179
+ # Retrieve saved Brand Tonality
1180
+ elif "show my saved brand tonality" in prompt or "find my saved brand tonality" in prompt:
1181
+ if st.session_state.get("brand_tonality"):
1182
+ return "\n".join([f"- {entry['message']}" for entry in st.session_state["brand_tonality"].values()])
1183
+ else:
1184
+ return "You haven't saved any Brand Tonality entries yet."
1185
 
1186
+ return None # If no recognized command, proceed with general handling
1187
+
1188
+
1189
+ def delete_entry(category, entry_id, session_key):
1190
+ try:
1191
+ user_id = st.session_state["wix_user_id"]
1192
+ db.child("users").child(user_id).child(category).child(entry_id).remove()
1193
+ del st.session_state[session_key][entry_id] # Remove from session
1194
+ st.experimental_rerun() # Refresh sidebar
1195
+ except Exception as e:
1196
+ st.error(f"Error deleting entry: {e}")
1197
+
1198
+ # Function to download TrustBuilder as a .md file
1199
+ def download_trustbuilder_as_md(content, trustbuilder_id):
1200
+ b64_content = base64.b64encode(content.encode()).decode()
1201
+ download_link = f'<a href="data:text/markdown;base64,{b64_content}" download="TrustBuilder_{trustbuilder_id}.md">Download</a>'
1202
+ st.sidebar.markdown(download_link, unsafe_allow_html=True)
1203
+
1204
+
1205
+
1206
+
1207
+
1208
+
1209
+ # Function to update the message counter in a static location
1210
+ message_counter_placeholder = st.sidebar.empty()
1211
+
1212
+ def update_message_counter():
1213
+ remaining_messages = st.session_state["message_limit"] - st.session_state["used_messages"]
1214
+ message_counter_placeholder.markdown(f"**Messages Left**: {remaining_messages} / {st.session_state['message_limit']}")
1215
+
1216
+ if st.session_state.get("wix_user_id") and st.session_state.get("email"):
1217
+ retrieve_user_data(st.session_state["wix_user_id"])
1218
+ display_saved_trustbuilders()
1219
+
1220
+ user_name = extract_name(st.session_state["email"])
1221
+ welcome_placeholder = st.empty()
1222
+ welcome_placeholder.info(f"**Hello, {user_name}!**")
1223
+ time.sleep(3)
1224
+ welcome_placeholder.empty()
1225
+ def check_user_subscription(wix_user_id):
1226
+ response = requests.get(f"{backend_url}/check-subscription/{wix_user_id}")
1227
+ if response.status_code == 200:
1228
+ data = response.json()
1229
+ st.session_state["message_limit"] = data.get("message_limit", 0)
1230
+ st.session_state["used_messages"] = data.get("used_messages", 0)
1231
+ update_message_counter()
1232
+ else:
1233
+ st.error("Error fetching user subscription details.")
1234
+
1235
+ def update_message_usage(wix_user_id):
1236
+ response = requests.post(f"{backend_url}/update-message-usage/{st.session_state['wix_user_id']}")
1237
+ if response.status_code == 200:
1238
+ st.session_state["used_messages"] += 1
1239
+ update_message_counter()
1240
+ else:
1241
+ st.error("Error updating message usage.")
1242
+ check_user_subscription(st.session_state["wix_user_id"])
1243
+
1244
+ # Input for AI interaction
1245
+ prompt = st.chat_input("")
1246
+ global combined_text
1247
+ if st.session_state["used_messages"] < st.session_state["message_limit"]:
1248
+ if prompt:
1249
+ st.session_state.chat_started = True
1250
+ st.session_state.chat_history.append({"role": "user", "content": prompt})
1251
+
1252
+ # Check if the prompt is a memory query
1253
+ memory_response = handle_memory_queries(prompt)
1254
+ if memory_response:
1255
+ with st.chat_message("assistant"):
1256
+ st.markdown(memory_response)
1257
 
1258
+ else:
1259
+ # Detect if the user wants to save content based on chatbox prompts
1260
+ save_as_trustbuilder = re.search(r"\b(save|add|store)\s*(this)?\s*(as)?\s*(trust\s*builder|trustbuilder)\b", prompt, re.IGNORECASE)
1261
+ save_as_tonality = re.search(r"\b(save|add|store)\s*(this)?\s*(as)?\s*(brand\s*tonality|tonality)\b", prompt, re.IGNORECASE)
1262
+
1263
+
1264
+ if save_as_trustbuilder or save_as_tonality:
1265
+ user_id = st.session_state["wix_user_id"]
1266
+ if save_as_trustbuilder:
1267
+ store_trustbuilder(user_id, prompt)
1268
+ display_save_confirmation("TrustBuilder")
1269
+ elif save_as_tonality:
1270
+ store_brand_tonality(user_id, prompt)
1271
+ display_save_confirmation("Brand Tonality")
1272
+
1273
+ else:
1274
+ # Generate a response with AI for other types of queries
1275
+ with st.chat_message("user"):
1276
+ st.markdown(prompt)
1277
+ response_placeholder = st.empty()
1278
+ with response_placeholder:
1279
+ with st.chat_message("assistant"):
1280
+ add_dot_typing_animation()
1281
+ display_typing_indicator()
1282
+ cleaned_text = ""
1283
+ # Specialized responses if keywords detected
1284
+ try:
1285
+ #if "trustbuilder" in prompt.lower() or "trust" in prompt.lower():
1286
+ output = agent_executor.invoke({
1287
+ "input": f"{prompt}Be in natural tone.Sources should be accurate.Avoid AI jargons.DONOT USE use words that end with '-ing' for headlines and subheadlines when asked to write a article,blog,newsletter.",
1288
+ "chat_history": st.session_state.chat_history
1289
+ })
1290
+ full_response = output["output"]
1291
+ #full_response= replace_terms(full_response)
1292
+
1293
+ cleaned_text = clean_text(full_response)
1294
+ trust_tip, suggestion = get_trust_tip_and_suggestion()
1295
+ combined_text = f"{cleaned_text}\n\n---\n\n**Trust Tip**: {trust_tip}\n\n**Suggestion**: {suggestion}"
1296
+ with response_placeholder:
1297
+ with st.chat_message("assistant"):
1298
+ st.markdown(combined_text, unsafe_allow_html=True)
1299
+
1300
+ #else:
1301
+ # llm = ChatOpenAI(model="gpt-4o", temperature=0.8)
1302
+ # output = llm.invoke(prompt)
1303
+ # full_response = output["output"]
1304
+ #full_response= replace_terms(full_response)
1305
+
1306
+ # cleaned_text = clean_text(full_response)
1307
+ # trust_tip, suggestion = get_trust_tip_and_suggestion()
1308
+ # combined_text = f"{cleaned_text}\n\n---\n\n**Trust Tip**: {trust_tip}\n\n**Suggestion**: {suggestion}"
1309
+ # with response_placeholder:
1310
+ # with st.chat_message("assistant"):
1311
+ # st.markdown(combined_text, unsafe_allow_html=True)
1312
+
1313
+ update_message_usage(st.session_state["wix_user_id"])
1314
+
1315
+ except Exception as e:
1316
+ logger.error(f"Error generating response: {e}")
1317
+ st.error("An error occurred while generating the response. Please try again.")
1318
+
1319
+ st.session_state.chat_history.append({"role": "assistant", "content": cleaned_text})
1320
+ copy_to_clipboard(cleaned_text)
1321
+ else:
1322
+ st.warning("You have reached your message limit. Please upgrade your plan to continue.")
1323
+ else:
1324
+ st.warning("Please log in to access the chatbot features.")