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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +196 -274
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_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,72 +12,46 @@ 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
- # ----------------- 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
@@ -88,147 +62,117 @@ class User:
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
@@ -243,131 +187,71 @@ def get_system_prompt():
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")
@@ -375,25 +259,63 @@ def main():
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()
 
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
  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
+ # Create users table with admin flag
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 INTEGER DEFAULT 0)''')
29
 
30
+ # Create company settings table
 
 
 
 
 
 
 
 
 
 
31
  c.execute('''CREATE TABLE IF NOT EXISTS company_settings
32
+ (id INTEGER PRIMARY KEY AUTOINCREMENT,
33
+ company_name TEXT,
34
+ company_business TEXT,
35
+ agent_name TEXT,
36
+ key_features TEXT)''')
37
 
38
+ # Initialize default company settings if empty
39
  c.execute('SELECT COUNT(*) FROM company_settings')
40
  if c.fetchone()[0] == 0:
41
  c.execute('''INSERT INTO company_settings
42
+ (company_name, company_business, agent_name, key_features)
43
  VALUES (?, ?, ?, ?)''',
44
+ ("TechElectronics", "Consumer Electronics Retailer", "Alex",
45
+ "Cutting-edge technology, Competitive pricing, Excellent customer service"))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
  conn.commit()
48
  return conn
49
 
50
  conn = init_db()
51
 
52
+ # --- User Class ---
 
53
  class User:
54
+ def __init__(self, id, username, password, chat_history=None, products_bought=None, is_admin=False):
 
55
  self.id = id
56
  self.username = username
57
  self.password = password
 
62
  @classmethod
63
  def create(cls, username, password, is_admin=False):
64
  hashed_pw = generate_password_hash(password)
65
+ conn = sqlite3.connect('users.db')
66
+ c = conn.cursor()
67
+ c.execute('INSERT INTO users (username, password, is_admin) VALUES (?, ?, ?)',
68
+ (username, hashed_pw, is_admin))
69
+ user_id = c.lastrowid
70
+ conn.commit()
71
+ conn.close()
72
+ return cls(user_id, username, hashed_pw, is_admin=is_admin)
73
 
74
  @classmethod
75
  def get_by_username(cls, username):
76
+ conn = sqlite3.connect('users.db')
77
+ c = conn.cursor()
78
+ c.execute('SELECT * FROM users WHERE username = ?', (username,))
79
+ user = c.fetchone()
80
+ conn.close()
81
+ if user:
82
+ return cls(user[0], user[1], user[2],
83
+ eval(user[3]) if user[3] else [],
84
+ eval(user[4]) if user[4] else [],
85
+ is_admin=user[5])
86
  return None
87
 
88
  def update_chat_history(self, new_messages):
89
+ conn = sqlite3.connect('users.db')
90
+ c = conn.cursor()
91
+ updated_history = self.chat_history + new_messages
92
+ c.execute('UPDATE users SET previous_chat_history = ? WHERE id = ?',
93
+ (str(updated_history), self.id))
94
+ conn.commit()
95
+ conn.close()
96
 
97
  def update_products_bought(self, new_products):
98
+ conn = sqlite3.connect('users.db')
99
+ c = conn.cursor()
100
+ updated_products = self.products_bought + new_products
101
+ c.execute('UPDATE users SET previous_products_bought = ? WHERE id = ?',
102
+ (str(updated_products), self.id))
103
+ conn.commit()
104
+ conn.close()
105
 
106
+ # --- Company Settings Functions ---
107
+ def get_company_settings():
108
+ conn = sqlite3.connect('users.db')
109
+ c = conn.cursor()
110
+ c.execute('SELECT * FROM company_settings ORDER BY id DESC LIMIT 1')
111
+ settings = c.fetchone()
112
+ conn.close()
113
+ if settings:
114
+ return {
115
+ 'company_name': settings[1],
116
+ 'company_business': settings[2],
117
+ 'agent_name': settings[3],
118
+ 'key_features': settings[4]
119
+ }
120
+ return None
121
 
122
+ def update_company_settings(company_name, company_business, agent_name, key_features):
123
+ conn = sqlite3.connect('users.db')
124
+ c = conn.cursor()
125
+ c.execute('''INSERT INTO company_settings
126
+ (company_name, company_business, agent_name, key_features)
127
+ VALUES (?, ?, ?, ?)''',
128
+ (company_name, company_business, agent_name, key_features))
129
+ conn.commit()
130
+ conn.close()
 
131
 
132
+ # --- AI Agent Setup ---
133
+ os.environ["GROQ_API_KEY"] = st.secrets["GROQ_API_KEY"]
134
+ llm = ChatGroq(
135
+ temperature=0.1,
136
+ model_name="llama3-8b-8192",
137
+ api_key=st.secrets["GROQ_API_KEY"],
138
+ )
 
 
139
 
140
+ embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")
 
 
 
 
 
141
 
142
+ @st.cache_resource
143
+ def load_data():
144
+ loader = CSVLoader(file_path="electronics_products.csv")
145
+ docs = loader.load()
146
+ text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
147
+ splits = text_splitter.split_documents(docs)
148
+ vectorstore = InMemoryVectorStore.from_documents(documents=splits, embedding=embeddings)
149
+ return vectorstore.as_retriever()
 
 
 
 
 
 
150
 
151
+ retriever = load_data()
 
 
 
 
 
 
 
 
 
152
 
153
+ def retrieve_query(query: str):
154
+ return retriever.get_relevant_documents(query)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155
 
156
+ tool = Tool(
157
+ name="retriever",
158
+ func=retrieve_query,
159
+ description="Useful for retrieving product information"
160
+ )
161
 
162
+ @st.cache_resource
163
+ def create_agent_executor(company_name, company_business, agent_name, key_features):
164
+ system_prompt = """
165
+ You are {agent_name}, the AI Sales Assistant for {company_name} ({company_business}).
166
+
167
+ Company Profile:
168
+ - Company Name: {company_name}
169
+ - Business: {company_business}
170
+ - Key Features: {key_features}
 
 
171
 
172
+ Product Availability:
173
+ - Only recommend and discuss products listed in the provided document.
174
+ - Do not suggest unavailable or out-of-stock products.
175
+ - Always verify product availability before making recommendations.
176
 
177
  Conversation Flow:
178
  1. Introduction
 
187
  - Maintain natural, professional conversations
188
  - Follow company policies
189
  - Be helpful and polite
190
+ - Always cross-check product recommendations with the available inventory
191
  """
192
 
193
+ formatted_system_prompt = system_prompt.format(
194
+ agent_name=agent_name,
195
+ company_name=company_name,
196
+ company_business=company_business,
197
+ key_features=key_features
 
 
198
  )
199
+
200
  prompt = ChatPromptTemplate.from_messages([
201
+ ("system", formatted_system_prompt),
202
  MessagesPlaceholder(variable_name="chat_history"),
203
  ("human", "{input}"),
204
  MessagesPlaceholder(variable_name="agent_scratchpad")
205
  ])
206
+
207
  agent = create_tool_calling_agent(llm, [tool], prompt)
208
  return AgentExecutor(agent=agent, tools=[tool], verbose=True)
209
 
210
+ # --- Admin Dashboard ---
211
  def admin_dashboard():
212
+ st.header("Admin Dashboard")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
+ # Company Settings Form
215
+ settings = get_company_settings()
216
+ with st.expander("Company Configuration", expanded=True):
217
+ with st.form("company_settings"):
218
+ st.subheader("Company Settings")
219
+ new_company_name = st.text_input("Company Name", value=settings['company_name'])
220
+ new_company_business = st.text_input("Company Business", value=settings['company_business'])
221
+ new_agent_name = st.text_input("Agent Name", value=settings['agent_name'])
222
+ new_key_features = st.text_area("Key Features", value=settings['key_features'])
223
+
224
+ if st.form_submit_button("Update Settings"):
225
+ update_company_settings(new_company_name, new_company_business,
226
+ new_agent_name, new_key_features)
227
+ st.success("Company settings updated successfully!")
228
 
229
+ # Product Management
230
+ with st.expander("Product Management"):
231
+ st.subheader("Update Product Catalog")
232
+ uploaded_file = st.file_uploader("Upload new product CSV", type="csv")
233
+ if uploaded_file is not None:
234
+ # Save the uploaded file
235
+ with open("electronics_products.csv", "wb") as f:
236
+ f.write(uploaded_file.getbuffer())
237
+ # Clear cache to reload data
238
+ load_data.clear()
239
+ st.success("Product catalog updated successfully!")
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
+ # --- Main Application ---
242
  def main():
243
+ st.title("AI Sales Assistant 🤖")
244
 
245
  if 'user' not in st.session_state:
246
  st.session_state.user = None
247
+ st.session_state.chat_history = []
248
+
249
+ # Authentication
250
  if not st.session_state.user:
251
+ st.header("Login/Register")
252
+ tab1, tab2 = st.tabs(["Login", "Register"])
253
 
254
+ with tab1:
255
  with st.form("Login"):
256
  username = st.text_input("Username")
257
  password = st.text_input("Password", type="password")
 
259
  user = User.get_by_username(username)
260
  if user and check_password_hash(user.password, password):
261
  st.session_state.user = user
262
+ st.session_state.chat_history = user.chat_history
263
  st.rerun()
264
  else:
265
  st.error("Invalid credentials")
266
 
267
+ with tab2:
268
  with st.form("Register"):
269
  new_user = st.text_input("New Username")
270
  new_pass = st.text_input("New Password", type="password")
271
+ admin_key = st.text_input("Admin Key (optional)", type="password")
272
+ if st.form_submit_button("Register"):
273
  if User.get_by_username(new_user):
274
+ st.error("Username already exists")
275
  else:
276
+ is_admin = admin_key == st.secrets.get("ADMIN_KEY", "")
277
+ user = User.create(new_user, new_pass, is_admin)
278
+ st.session_state.user = user
279
+ st.session_state.chat_history = []
280
  st.rerun()
281
  else:
282
  if st.session_state.user.is_admin:
283
  admin_dashboard()
284
  else:
285
+ settings = get_company_settings()
286
+ agent_executor = create_agent_executor(
287
+ settings['company_name'],
288
+ settings['company_business'],
289
+ settings['agent_name'],
290
+ settings['key_features']
291
+ )
292
+
293
+ st.header(f"Welcome to {settings['company_name']}, {st.session_state.user.username}!")
294
+ st.subheader(f"Chat with {settings['agent_name']}, your AI Sales Assistant")
295
+
296
+ if prompt := st.chat_input("Type your message here..."):
297
+ with st.chat_message("user"):
298
+ st.write(prompt)
299
+
300
+ with st.chat_message("assistant"):
301
+ response = agent_executor.invoke({
302
+ "input": prompt,
303
+ "chat_history": [HumanMessage(content=msg["content"]) if msg["type"] == "human"
304
+ else AIMessage(content=msg["content"])
305
+ for msg in st.session_state.chat_history]
306
+ })["output"]
307
+ st.write(response)
308
+
309
+ if "https://www.example.com/payment" in response:
310
+ st.session_state.user.update_products_bought(["Latest Product"])
311
+ st.success("Product added to your purchases!")
312
+
313
+ new_messages = [
314
+ {"type": "human", "content": prompt},
315
+ {"type": "ai", "content": response}
316
+ ]
317
+ st.session_state.user.update_chat_history(new_messages)
318
+ st.session_state.chat_history += new_messages
319
 
320
  if __name__ == "__main__":
321
  main()