Aniq-63 commited on
Commit
18a83b8
·
verified ·
1 Parent(s): 6b56d53

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +310 -175
app.py CHANGED
@@ -4,7 +4,7 @@ import streamlit as st
4
  from werkzeug.security import generate_password_hash, check_password_hash
5
  from langchain_groq import ChatGroq
6
  from langchain_huggingface import HuggingFaceEmbeddings
7
- from langchain_community.document_loaders.csv_loader import CSVLoader
8
  from langchain_text_splitters import RecursiveCharacterTextSplitter
9
  from langchain_core.vectorstores import InMemoryVectorStore
10
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
@@ -12,253 +12,388 @@ from langchain.tools import Tool
12
  from langchain.agents import AgentExecutor, create_tool_calling_agent
13
  from langchain_core.messages import HumanMessage, AIMessage
14
 
15
-
16
- # --- Database Setup ---
17
-
18
- # Database initialization with caching
19
  @st.cache_resource
20
  def init_db():
21
  conn = sqlite3.connect('users.db', check_same_thread=False)
22
  c = conn.cursor()
 
 
23
  c.execute('''CREATE TABLE IF NOT EXISTS users
24
  (id INTEGER PRIMARY KEY AUTOINCREMENT,
25
  username TEXT UNIQUE NOT NULL,
26
  password TEXT NOT NULL,
27
  previous_chat_history TEXT,
28
- previous_products_bought TEXT)''')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  conn.commit()
30
  return conn
31
 
32
  conn = init_db()
33
 
34
-
 
35
  class User:
36
- def __init__(self, id, username, password, chat_history = None, products_bought = None):
 
37
  self.id = id
38
  self.username = username
39
  self.password = password
40
  self.chat_history = chat_history or []
41
  self.products_bought = products_bought or []
 
42
 
43
- # To register a new user
44
  @classmethod
45
- def create(cls, username, password):
46
  hashed_pw = generate_password_hash(password)
47
- conn = sqlite3.connect('users.db')
48
- c = conn.cursor()
49
- c.execute('INSERT INTO users (username, password) VALUES (?, ?)',(username, hashed_pw))
50
- user_id = c.lastrowid
51
- conn.commit()
52
- conn.close()
53
- return cls(user_id, username, hashed_pw)
54
 
55
- # To retrieve an existing user from the database by username.
56
  @classmethod
57
  def get_by_username(cls, username):
58
- conn = sqlite3.connect('users.db')
59
- c = conn.cursor()
60
- c.execute('SELECT * FROM users WHERE username = ?', (username,))
61
- user = c.fetchone()
62
- conn.close()
63
- if user:
64
- return cls(user[0], user[1], user[2],
65
- eval(user[3]) if user[3] else [],
66
- eval(user[4]) if user[4] else [])
67
  return None
68
 
69
  def update_chat_history(self, new_messages):
70
- conn = sqlite3.connect('users.db')
71
- c = conn.cursor()
72
- updated_history = self.chat_history + new_messages
73
- c.execute('UPDATE users SET previous_chat_history = ? WHERE id = ?',
74
- (str(updated_history), self.id))
75
- conn.commit()
76
- conn.close()
77
 
78
  def update_products_bought(self, new_products):
79
- conn = sqlite3.connect('users.db')
80
- c = conn.cursor()
81
- updated_products = self.products_bought + new_products
82
- c.execute('UPDATE users SET previous_products_bought = ? WHERE id = ?',
83
- (str(updated_products), self.id))
84
- conn.commit()
85
- conn.close()
86
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
 
88
- # --- AI Agent Setup ---
89
- # Load the LLM model from Groq
90
- os.environ["GROQ_API_KEY"] = st.secrets["GROQ_API_KEY"]
91
- llm = ChatGroq(
92
- temperature=0.1,
93
- model_name="llama3-8b-8192",
94
- api_key=st.secrets["GROQ_API_KEY"],
95
- )
96
 
97
- # Load the HuggingFace Embeddings
98
- embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
- # Load and process CSV data
 
 
 
 
 
 
 
 
 
 
 
101
  @st.cache_resource
102
- def load_data():
103
- loader = CSVLoader(file_path="electronics_products.csv")
104
- docs = loader.load()
105
- text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
106
- splits = text_splitter.split_documents(docs)
107
- vectorstore = InMemoryVectorStore.from_documents(documents=splits, embedding=embeddings)
108
- return vectorstore.as_retriever()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
- retriever = load_data()
111
 
112
- def retrieve_query(query: str):
113
- """Retrieves documents related to the query."""
114
- return retriever.get_relevant_documents(query)
 
 
 
 
 
 
 
 
115
 
116
- tool = Tool(
117
- name="retriever",
118
- func=retrieve_query,
119
- description="Useful for retrieving product information"
120
- )
121
 
122
- # Agent setup
123
- # System prompt template
124
- system_prompt = """
125
- You are {agent_name}, the AI Sales Assistant for {company_name} ({company_business}).
 
 
 
 
126
 
127
- Company Profile:
128
- - Company Name: {company_name}
129
- - Business: {company_business}
130
- - Key Features: {key_features}
 
131
 
132
- Product Availability:
133
- - Only recommend and discuss products listed in the provided in document.
134
- - Do not suggest unavailable or out-of-stock products.
135
- - Always verify product availability before making recommendations.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- Conversation Flow:
138
- 1. Introduction
139
- 2. Qualification
140
- 3. Understanding Needs
141
- 4. Needs Analysis
142
- 5. Solution Presentation (Only recommend available products)
143
- 6. Confirmation
144
- 7. If the prospect agrees to purchase, thank them and provide the payment link: https://www.example.com/payment
 
 
 
 
 
 
 
145
 
146
- Guidelines:
147
- - Maintain natural, professional conversations
148
- - Follow company policies
149
- - Be helpful and polite
150
- - Always cross-check product recommendations with the available inventory in the CSV document
151
- """
 
 
 
 
 
 
 
 
 
152
 
153
- # Define the company and agent details
154
- company_name = "TechElectronics"
155
- company_business = "Consumer Electronics Retailer"
156
- agent_name = "Alex"
157
- key_features = "Cutting-edge technology, Competitive pricing, Excellent customer service"
 
 
 
 
 
 
 
 
 
 
 
158
 
159
- # Format the system prompt with the company and agent details
160
- formatted_system_prompt = system_prompt.format(
161
- agent_name=agent_name,
162
- company_name=company_name,
163
- company_business=company_business,
164
- key_features=key_features
165
- )
166
 
167
- prompt = ChatPromptTemplate.from_messages([
168
- ("system", formatted_system_prompt),
169
- MessagesPlaceholder(variable_name="chat_history"),
170
- ("human", "{input}"),
171
- MessagesPlaceholder(variable_name="agent_scratchpad")
172
- ])
 
 
 
 
 
173
 
174
- tools = [tool]
175
- agent = create_tool_calling_agent(llm, tools, prompt)
176
- agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
177
 
 
 
 
 
 
 
178
 
179
- # --- Streamlit UI ---
180
  def main():
181
- st.title(f"{company_name} AI Sales Assistant 🤖")
182
 
183
- # Initialize session state
184
  if 'user' not in st.session_state:
185
  st.session_state.user = None
186
- st.session_state.chat_history = []
187
 
188
- # Authentication
189
  if not st.session_state.user:
190
- st.header("Login/Register")
191
- tab1, tab2 = st.tabs(["Login", "Register"])
192
 
193
- with tab1:
194
  with st.form("Login"):
195
  username = st.text_input("Username")
196
  password = st.text_input("Password", type="password")
197
  if st.form_submit_button("Login"):
198
  user = User.get_by_username(username)
199
  if user and check_password_hash(user.password, password):
200
- # If valid, the user is stored in st.session_state.user and their chat history is loaded.
201
  st.session_state.user = user
202
- st.session_state.chat_history = user.chat_history
203
  st.rerun()
204
  else:
205
  st.error("Invalid credentials")
206
 
207
- with tab2:
208
  with st.form("Register"):
209
  new_user = st.text_input("New Username")
210
  new_pass = st.text_input("New Password", type="password")
211
- if st.form_submit_button("Register"):
212
  if User.get_by_username(new_user):
213
- st.error("Username already exists")
214
  else:
215
- user = User.create(new_user, new_pass)
216
- st.session_state.user = user
217
- st.session_state.chat_history = []
218
  st.rerun()
219
-
220
  else:
221
- # Chat Interface
222
- st.header(f"Welcome to {company_name}, {st.session_state.user.username}😊!")
223
- st.subheader("Chat with our AI Sales Assistant")
224
-
225
- # # Display chat history
226
- # for msg in st.session_state.chat_history:
227
- # if msg["type"] == "human":
228
- # with st.chat_message("user"):
229
- # st.write(msg["content"])
230
- # else:
231
- # with st.chat_message("assistant"):
232
- # st.write(msg["content"])
233
-
234
- if prompt := st.chat_input("Type you Message here..."):
235
- #Add user message to chat
236
- with st.chat_message("user"):
237
- st.write(prompt)
238
-
239
- # Get AI response
240
- with st.chat_message("assistant"):
241
- response = agent_executor.invoke({
242
- "input": prompt,
243
- "chat_history": [HumanMessage(content=msg["content"]) if msg["type"] == "human" else AIMessage(content=msg["content"])
244
- for msg in st.session_state.chat_history]
245
- })["output"]
246
- st.write(response)
247
-
248
- # Check if payment link is provided
249
- if "https://www.example.com/payment" in response:
250
- st.session_state.user.update_products_bought(["Latest Product"])
251
- st.success("Product added to your purchases!")
252
-
253
- # Update chat history in database
254
- new_messages = [
255
- {"type": "human", "content": prompt},
256
- {"type": "ai", "content": response}
257
- ]
258
- # Both the user’s message and the assistant’s reply are appended to the persistent chat history
259
- # (both in session and in the database), ensuring conversation continuity.
260
- st.session_state.user.update_chat_history(new_messages)
261
- st.session_state.chat_history += new_messages
262
 
263
  if __name__ == "__main__":
264
- main()
 
4
  from werkzeug.security import generate_password_hash, check_password_hash
5
  from langchain_groq import ChatGroq
6
  from langchain_huggingface import HuggingFaceEmbeddings
7
+ from langchain_core.documents import Document
8
  from langchain_text_splitters import RecursiveCharacterTextSplitter
9
  from langchain_core.vectorstores import InMemoryVectorStore
10
  from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
 
12
  from langchain.agents import AgentExecutor, create_tool_calling_agent
13
  from langchain_core.messages import HumanMessage, AIMessage
14
 
15
+ # ----------------- Database Setup -----------------
 
 
 
16
  @st.cache_resource
17
  def init_db():
18
  conn = sqlite3.connect('users.db', check_same_thread=False)
19
  c = conn.cursor()
20
+
21
+ # Users Table
22
  c.execute('''CREATE TABLE IF NOT EXISTS users
23
  (id INTEGER PRIMARY KEY AUTOINCREMENT,
24
  username TEXT UNIQUE NOT NULL,
25
  password TEXT NOT NULL,
26
  previous_chat_history TEXT,
27
+ previous_products_bought TEXT,
28
+ is_admin BOOLEAN DEFAULT 0)''')
29
+
30
+ # Products Table
31
+ c.execute('''CREATE TABLE IF NOT EXISTS products
32
+ (product_id INTEGER PRIMARY KEY AUTOINCREMENT,
33
+ name TEXT NOT NULL,
34
+ description TEXT,
35
+ price REAL,
36
+ stock INTEGER,
37
+ category TEXT,
38
+ features TEXT)''')
39
+
40
+ # Company Settings Table
41
+ c.execute('''CREATE TABLE IF NOT EXISTS company_settings
42
+ (id INTEGER PRIMARY KEY,
43
+ company_name TEXT DEFAULT 'TechElectronics',
44
+ business_type TEXT DEFAULT 'Consumer Electronics Retailer',
45
+ key_features TEXT DEFAULT 'Cutting-edge technology, Competitive pricing, Excellent customer service',
46
+ payment_link TEXT DEFAULT 'https://www.example.com/payment')''')
47
+
48
+ # Initialize Default Data
49
+ c.execute('SELECT COUNT(*) FROM company_settings')
50
+ if c.fetchone()[0] == 0:
51
+ c.execute('''INSERT INTO company_settings
52
+ (company_name, business_type, key_features, payment_link)
53
+ VALUES (?, ?, ?, ?)''',
54
+ ('TechElectronics',
55
+ 'Consumer Electronics Retailer',
56
+ 'Cutting-edge technology, Competitive pricing, Excellent customer service',
57
+ 'https://www.example.com/payment'))
58
+
59
+ c.execute('SELECT COUNT(*) FROM products')
60
+ if c.fetchone()[0] == 0:
61
+ sample_products = [
62
+ ('Smartphone X', 'Flagship smartphone with AI camera', 799.99, 50,
63
+ 'Phones', '5G, 128GB Storage, 48MP Camera'),
64
+ ('4K Smart TV', '55-inch 4K Android TV', 899.99, 30,
65
+ 'TVs', 'HDR10+, Dolby Atmos, Smart Assistant')
66
+ ]
67
+ c.executemany('''INSERT INTO products
68
+ (name, description, price, stock, category, features)
69
+ VALUES (?, ?, ?, ?, ?, ?)''', sample_products)
70
+
71
  conn.commit()
72
  return conn
73
 
74
  conn = init_db()
75
 
76
+ # ----------------- Data Management Classes -----------------
77
+ # User Mangement system
78
  class User:
79
+ def __init__(self, id, username, password, chat_history=None,
80
+ products_bought=None, is_admin=False):
81
  self.id = id
82
  self.username = username
83
  self.password = password
84
  self.chat_history = chat_history or []
85
  self.products_bought = products_bought or []
86
+ self.is_admin = is_admin
87
 
 
88
  @classmethod
89
+ def create(cls, username, password, is_admin=False):
90
  hashed_pw = generate_password_hash(password)
91
+ with sqlite3.connect('users.db') as conn:
92
+ c = conn.cursor()
93
+ c.execute('''INSERT INTO users (username, password, is_admin)
94
+ VALUES (?, ?, ?)''',
95
+ (username, hashed_pw, is_admin))
96
+ return cls(c.lastrowid, username, hashed_pw, is_admin=is_admin)
 
97
 
 
98
  @classmethod
99
  def get_by_username(cls, username):
100
+ with sqlite3.connect('users.db') as conn:
101
+ c = conn.cursor()
102
+ c.execute('SELECT * FROM users WHERE username = ?', (username,))
103
+ user = c.fetchone()
104
+ if user:
105
+ return cls(user[0], user[1], user[2],
106
+ eval(user[3]) if user[3] else [],
107
+ eval(user[4]) if user[4] else [],
108
+ user[5])
109
  return None
110
 
111
  def update_chat_history(self, new_messages):
112
+ with sqlite3.connect('users.db') as conn:
113
+ c = conn.cursor()
114
+ updated_history = self.chat_history + new_messages
115
+ c.execute('''UPDATE users SET previous_chat_history = ?
116
+ WHERE id = ?''', (str(updated_history), self.id))
117
+ conn.commit()
 
118
 
119
  def update_products_bought(self, new_products):
120
+ with sqlite3.connect('users.db') as conn:
121
+ c = conn.cursor()
122
+ updated_products = self.products_bought + new_products
123
+ c.execute('''UPDATE users SET previous_products_bought = ?
124
+ WHERE id = ?''', (str(updated_products), self.id))
125
+ conn.commit()
126
+
127
+ # Product Management system
128
+ class ProductManager:
129
+ @staticmethod
130
+ def get_all_products():
131
+ with sqlite3.connect('users.db') as conn:
132
+ c = conn.cursor()
133
+ c.execute('SELECT * FROM products')
134
+ return c.fetchall()
135
+
136
+ @staticmethod
137
+ def update_product(product_id, name, description, price, stock, category, features):
138
+ with sqlite3.connect('users.db') as conn:
139
+ c = conn.cursor()
140
+ c.execute('''UPDATE products SET
141
+ name=?, description=?, price=?, stock=?,
142
+ category=?, features=?
143
+ WHERE product_id=?''',
144
+ (name, description, price, stock, category, features, product_id))
145
+ conn.commit()
146
+
147
+ @staticmethod
148
+ def add_product(name, description, price, stock, category, features):
149
+ with sqlite3.connect('users.db') as conn:
150
+ c = conn.cursor()
151
+ c.execute('''INSERT INTO products
152
+ (name, description, price, stock, category, features)
153
+ VALUES (?, ?, ?, ?, ?, ?)''',
154
+ (name, description, price, stock, category, features))
155
+ conn.commit()
156
 
157
+ @staticmethod
158
+ def delete_product(product_id):
159
+ with sqlite3.connect('users.db') as conn:
160
+ c = conn.cursor()
161
+ c.execute('DELETE FROM products WHERE product_id=?', (product_id,))
162
+ conn.commit()
 
 
163
 
164
+ # Company Setting
165
+ class CompanyManager:
166
+ @staticmethod
167
+ def get_settings():
168
+ with sqlite3.connect('users.db') as conn:
169
+ c = conn.cursor()
170
+ c.execute('SELECT * FROM company_settings WHERE id=1')
171
+ settings = c.fetchone()
172
+ return {
173
+ 'company_name': settings[1],
174
+ 'business_type': settings[2],
175
+ 'key_features': settings[3],
176
+ 'payment_link': settings[4]
177
+ }
178
 
179
+ @staticmethod
180
+ def update_settings(name, business, features, payment_link):
181
+ with sqlite3.connect('users.db') as conn:
182
+ c = conn.cursor()
183
+ c.execute('''UPDATE company_settings SET
184
+ company_name=?, business_type=?,
185
+ key_features=?, payment_link=?
186
+ WHERE id=1''',
187
+ (name, business, features, payment_link))
188
+ conn.commit()
189
+
190
+ # ----------------- AI Agent Setup -----------------
191
  @st.cache_resource
192
+ def initialize_ai():
193
+ os.environ["GROQ_API_KEY"] = st.secrets["GROQ_API_KEY"]
194
+ llm = ChatGroq(
195
+ temperature=0.1,
196
+ model_name="llama3-8b-8192",
197
+ api_key=st.secrets["GROQ_API_KEY"],
198
+ )
199
+
200
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
201
+
202
+ def refresh_vectorstore():
203
+ products = ProductManager.get_all_products()
204
+ docs = []
205
+ for p in products:
206
+ docs.append(Document(
207
+ page_content=f"Name: {p[1]}\nDescription: {p[2]}\nPrice: {p[3]}\nStock: {p[4]}\nCategory: {p[5]}\nFeatures: {p[6]}",
208
+ metadata={"product_id": p[0]}
209
+ ))
210
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
211
+ splits = text_splitter.split_documents(docs)
212
+ return InMemoryVectorStore.from_documents(splits, embeddings).as_retriever()
213
+
214
+ return llm, embeddings, refresh_vectorstore
215
 
216
+ llm, embeddings, refresh_vectorstore = initialize_ai()
217
 
218
+ def get_system_prompt():
219
+ settings = CompanyManager.get_settings()
220
+ return f"""
221
+ You are {settings['company_name']}'s AI Sales Assistant specializing in {settings['business_type']}.
222
+ Key Features: {settings['key_features']}
223
+
224
+ Guidelines:
225
+ 1. Only recommend products with stock > 0
226
+ 2. Always verify prices before confirming
227
+ 3. Use payment link: {settings['payment_link']}
228
+ 4. Maintain professional and friendly tone
229
 
230
+ Current Products:
231
+ {[p[1] for p in ProductManager.get_all_products()]}
 
 
 
232
 
233
+ Conversation Flow:
234
+ 1. Introduction
235
+ 2. Qualification
236
+ 3. Understanding Needs
237
+ 4. Needs Analysis
238
+ 5. Solution Presentation (Only recommend available products)
239
+ 6. Confirmation
240
+ 7. If the prospect agrees to purchase, thank them and provide the payment link: https://www.example.com/payment
241
 
242
+ Guidelines:
243
+ - Maintain natural, professional conversations
244
+ - Follow company policies
245
+ - Be helpful and polite
246
+ """
247
 
248
+ def create_agent_executor():
249
+ retriever = refresh_vectorstore()
250
+
251
+ tool = Tool(
252
+ name="product_retriever",
253
+ func=lambda q: retriever.get_relevant_documents(q),
254
+ description="Access current product information"
255
+ )
256
+
257
+ prompt = ChatPromptTemplate.from_messages([
258
+ ("system", get_system_prompt()),
259
+ MessagesPlaceholder(variable_name="chat_history"),
260
+ ("human", "{input}"),
261
+ MessagesPlaceholder(variable_name="agent_scratchpad")
262
+ ])
263
+
264
+ agent = create_tool_calling_agent(llm, [tool], prompt)
265
+ return AgentExecutor(agent=agent, tools=[tool], verbose=True)
266
 
267
+ # ----------------- Streamlit UI -----------------
268
+ def admin_dashboard():
269
+ st.sidebar.header("Company Configuration")
270
+ with st.sidebar.form("Company Settings"):
271
+ settings = CompanyManager.get_settings()
272
+ company_name = st.text_input("Company Name", value=settings['company_name'])
273
+ business_type = st.text_area("Business Type", value=settings['business_type'])
274
+ key_features = st.text_area("Key Features", value=settings['key_features'])
275
+ payment_link = st.text_input("Payment Link", value=settings['payment_link'])
276
+
277
+ if st.form_submit_button("Update Settings"):
278
+ CompanyManager.update_settings(company_name, business_type,
279
+ key_features, payment_link)
280
+ st.success("Settings updated!")
281
+ st.cache_resource.clear()
282
 
283
+ st.header("Product Management")
284
+ tab1, tab2, tab3 = st.tabs(["Add Product", "Edit Products", "Delete Product"])
285
+
286
+ with tab1:
287
+ with st.form("Add Product"):
288
+ name = st.text_input("Product Name")
289
+ desc = st.text_area("Description")
290
+ price = st.number_input("Price", min_value=0.0)
291
+ stock = st.number_input("Stock", min_value=0)
292
+ category = st.text_input("Category")
293
+ features = st.text_input("Features")
294
+ if st.form_submit_button("Add Product"):
295
+ ProductManager.add_product(name, desc, price, stock, category, features)
296
+ refresh_vectorstore()
297
+ st.success("Product added!")
298
 
299
+ with tab2:
300
+ products = ProductManager.get_all_products()
301
+ selected = st.selectbox("Select Product", products, format_func=lambda x: x[1])
302
+ if selected:
303
+ with st.form("Edit Product"):
304
+ name = st.text_input("Name", value=selected[1])
305
+ desc = st.text_area("Description", value=selected[2])
306
+ price = st.number_input("Price", value=selected[3])
307
+ stock = st.number_input("Stock", value=selected[4])
308
+ category = st.text_input("Category", value=selected[5])
309
+ features = st.text_input("Features", value=selected[6])
310
+ if st.form_submit_button("Update"):
311
+ ProductManager.update_product(selected[0], name, desc,
312
+ price, stock, category, features)
313
+ refresh_vectorstore()
314
+ st.success("Product updated!")
315
 
316
+ with tab3:
317
+ products = ProductManager.get_all_products()
318
+ selected = st.selectbox("Select to Delete", products, format_func=lambda x: x[1])
319
+ if st.button("Delete"):
320
+ ProductManager.delete_product(selected[0])
321
+ refresh_vectorstore()
322
+ st.success("Product deleted!")
323
 
324
+ def user_interface():
325
+ settings = CompanyManager.get_settings()
326
+ st.title(f"{settings['company_name']} AI Assistant")
327
+
328
+ if 'chat_history' not in st.session_state:
329
+ st.session_state.chat_history = st.session_state.user.chat_history
330
+
331
+ for msg in st.session_state.chat_history:
332
+ role = "user" if msg["type"] == "human" else "assistant"
333
+ with st.chat_message(role):
334
+ st.write(msg["content"])
335
 
336
+ if prompt := st.chat_input("How can I help you today?"):
337
+ st.chat_message("user").write(prompt)
338
+
339
+ agent_executor = create_agent_executor()
340
+ response = agent_executor.invoke({
341
+ "input": prompt,
342
+ "chat_history": [
343
+ HumanMessage(content=msg["content"]) if msg["type"] == "human"
344
+ else AIMessage(content=msg["content"])
345
+ for msg in st.session_state.chat_history
346
+ ]
347
+ })["output"]
348
+
349
+ with st.chat_message("assistant"):
350
+ st.write(response)
351
+ if settings['payment_link'] in response:
352
+ st.markdown(f"[Complete Payment Here]({settings['payment_link']})")
353
 
354
+ new_messages = [
355
+ {"type": "human", "content": prompt},
356
+ {"type": "ai", "content": response}
357
+ ]
358
+ st.session_state.user.update_chat_history(new_messages)
359
+ st.session_state.chat_history += new_messages
360
 
 
361
  def main():
362
+ st.set_page_config(page_title="AI Sales Assistant", layout="wide")
363
 
 
364
  if 'user' not in st.session_state:
365
  st.session_state.user = None
 
366
 
 
367
  if not st.session_state.user:
368
+ auth_col1, auth_col2 = st.columns(2)
 
369
 
370
+ with auth_col1:
371
  with st.form("Login"):
372
  username = st.text_input("Username")
373
  password = st.text_input("Password", type="password")
374
  if st.form_submit_button("Login"):
375
  user = User.get_by_username(username)
376
  if user and check_password_hash(user.password, password):
 
377
  st.session_state.user = user
 
378
  st.rerun()
379
  else:
380
  st.error("Invalid credentials")
381
 
382
+ with auth_col2:
383
  with st.form("Register"):
384
  new_user = st.text_input("New Username")
385
  new_pass = st.text_input("New Password", type="password")
386
+ if st.form_submit_button("Create Account"):
387
  if User.get_by_username(new_user):
388
+ st.error("Username exists")
389
  else:
390
+ st.session_state.user = User.create(new_user, new_pass)
 
 
391
  st.rerun()
 
392
  else:
393
+ if st.session_state.user.is_admin:
394
+ admin_dashboard()
395
+ else:
396
+ user_interface()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
 
398
  if __name__ == "__main__":
399
+ main()