Maqsudbek commited on
Commit
fad6979
Β·
verified Β·
1 Parent(s): 8e32746

Update src/streamlit_app.py

Browse files
Files changed (1) hide show
  1. src/streamlit_app.py +1051 -35
src/streamlit_app.py CHANGED
@@ -1,40 +1,1056 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
- import streamlit as st
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
 
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
 
13
- In the meantime, below is an example of what you can do with just a few lines of code:
 
 
 
 
 
 
 
 
 
 
14
  """
15
 
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # import altair as alt
2
+ # import numpy as np
3
+ # import pandas as pd
4
+ # import streamlit as st
5
+
6
+ # """
7
+ # # Welcome to Streamlit!
8
+
9
+ # Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
+ # If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
+ # forums](https://discuss.streamlit.io).
12
+
13
+ # In the meantime, below is an example of what you can do with just a few lines of code:
14
+ # """
15
+
16
+ # num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
+ # num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
+
19
+ # indices = np.linspace(0, 1, num_points)
20
+ # theta = 2 * np.pi * num_turns * indices
21
+ # radius = indices
22
+
23
+ # x = radius * np.cos(theta)
24
+ # y = radius * np.sin(theta)
25
+
26
+ # df = pd.DataFrame({
27
+ # "x": x,
28
+ # "y": y,
29
+ # "idx": indices,
30
+ # "rand": np.random.randn(num_points),
31
+ # })
32
+
33
+ # st.altair_chart(alt.Chart(df, height=700, width=700)
34
+ # .mark_point(filled=True)
35
+ # .encode(
36
+ # x=alt.X("x", axis=None),
37
+ # y=alt.Y("y", axis=None),
38
+ # color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
+ # size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
+ # ))
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+
53
+
54
+
55
+
56
+
57
+
58
 
 
 
59
 
 
 
 
60
 
61
+
62
+
63
+
64
+
65
+
66
+ """
67
+ Advanced Business AI Assistant - Streamlit App
68
+ Deployed on Hugging Face Spaces
69
+
70
+ This comprehensive business assistant provides intelligent answers about your business,
71
+ integrates with multiple AI providers, and includes support ticket functionality.
72
  """
73
 
74
+ import streamlit as st
75
+ import time
76
+ import json
77
+ import os
78
+ import requests
79
+ from datetime import datetime, timedelta
80
+ from typing import Dict, List, Optional, Any
81
+ import uuid
82
+ import hashlib
83
+
84
+ # Import the streaming system
85
+ try:
86
+ from streaming import AdvancedStreamingSystem, StreamProvider, StreamingConfig
87
+ STREAMING_AVAILABLE = True
88
+ except ImportError:
89
+ STREAMING_AVAILABLE = False
90
+
91
+ # Page configuration
92
+ st.set_page_config(
93
+ page_title="AgentAI Business Assistant",
94
+ page_icon="🏒",
95
+ layout="wide",
96
+ initial_sidebar_state="expanded"
97
+ )
98
+
99
+ # Business Information Database
100
+ BUSINESS_INFO = {
101
+ "company_name": "AgentAI Solutions",
102
+ "tagline": "Advanced AI Development & Consulting",
103
+ "description": "We specialize in cutting-edge AI solutions, machine learning implementations, and intelligent automation systems for businesses worldwide.",
104
+
105
+ "contact": {
106
+ "phone": "+1 (555) 123-4567",
107
+ "email": "[email protected]",
108
+ "support_email": "[email protected]",
109
+ "website": "https://agentai-solutions.com",
110
+ "linkedin": "https://linkedin.com/company/agentai-solutions"
111
+ },
112
+
113
+ "location": {
114
+ "address": "123 Innovation Drive, Tech District",
115
+ "city": "San Francisco",
116
+ "state": "CA",
117
+ "zip": "94105",
118
+ "country": "USA",
119
+ "timezone": "PST (UTC-8)",
120
+ "coordinates": {"lat": 37.7749, "lon": -122.4194}
121
+ },
122
+
123
+ "hours": {
124
+ "monday": {"open": "9:00 AM", "close": "6:00 PM", "timezone": "PST"},
125
+ "tuesday": {"open": "9:00 AM", "close": "6:00 PM", "timezone": "PST"},
126
+ "wednesday": {"open": "9:00 AM", "close": "6:00 PM", "timezone": "PST"},
127
+ "thursday": {"open": "9:00 AM", "close": "6:00 PM", "timezone": "PST"},
128
+ "friday": {"open": "9:00 AM", "close": "6:00 PM", "timezone": "PST"},
129
+ "saturday": {"open": "10:00 AM", "close": "4:00 PM", "timezone": "PST"},
130
+ "sunday": "Closed",
131
+ "holidays": "Closed on major US holidays"
132
+ },
133
+
134
+ "services": [
135
+ {
136
+ "name": "AI Development",
137
+ "description": "Custom AI solutions, machine learning models, and intelligent automation systems",
138
+ "duration": "2-12 weeks",
139
+ "price_range": "$10,000 - $100,000+"
140
+ },
141
+ {
142
+ "name": "AI Consulting",
143
+ "description": "Strategic AI planning, feasibility studies, and implementation roadmaps",
144
+ "duration": "1-4 weeks",
145
+ "price_range": "$5,000 - $25,000"
146
+ },
147
+ {
148
+ "name": "Model Training",
149
+ "description": "Custom model training, fine-tuning, and optimization services",
150
+ "duration": "1-6 weeks",
151
+ "price_range": "$3,000 - $50,000"
152
+ },
153
+ {
154
+ "name": "AI Integration",
155
+ "description": "Seamless integration of AI solutions into existing business systems",
156
+ "duration": "2-8 weeks",
157
+ "price_range": "$7,500 - $75,000"
158
+ }
159
+ ],
160
+
161
+ "team": [
162
+ {"name": "Alex Chen", "role": "CEO & AI Architect", "expertise": "Machine Learning, Deep Learning"},
163
+ {"name": "Sarah Johnson", "role": "CTO & Lead Developer", "expertise": "MLOps, Cloud Architecture"},
164
+ {"name": "Dr. Michael Rodriguez", "role": "Head of Research", "expertise": "NLP, Computer Vision"},
165
+ {"name": "Emily Zhang", "role": "AI Consultant", "expertise": "Business Strategy, AI Ethics"}
166
+ ],
167
+
168
+ "support": {
169
+ "response_time": "24 hours for general inquiries, 4 hours for urgent issues",
170
+ "channels": ["Email", "Phone", "Live Chat", "Support Tickets"],
171
+ "emergency_contact": "+1 (555) 123-4567 ext. 911"
172
+ }
173
+ }
174
+
175
+ # Custom CSS for professional styling
176
+ st.markdown("""
177
+ <style>
178
+ .main-header {
179
+ font-size: 3rem;
180
+ color: #1E3A8A;
181
+ text-align: center;
182
+ margin-bottom: 1rem;
183
+ font-weight: bold;
184
+ }
185
+ .sub-header {
186
+ font-size: 1.2rem;
187
+ color: #64748B;
188
+ text-align: center;
189
+ margin-bottom: 2rem;
190
+ }
191
+ .business-card {
192
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
193
+ color: white;
194
+ padding: 2rem;
195
+ border-radius: 1rem;
196
+ margin: 1rem 0;
197
+ box-shadow: 0 10px 25px rgba(0,0,0,0.1);
198
+ }
199
+ .info-card {
200
+ background: white;
201
+ padding: 1.5rem;
202
+ border-radius: 0.8rem;
203
+ border-left: 4px solid #3B82F6;
204
+ margin: 1rem 0;
205
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
206
+ }
207
+ .chat-message {
208
+ padding: 1rem;
209
+ border-radius: 0.8rem;
210
+ margin: 0.5rem 0;
211
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
212
+ }
213
+ .user-message {
214
+ background: linear-gradient(135deg, #E3F2FD 0%, #BBDEFB 100%);
215
+ border-left: 4px solid #2196F3;
216
+ margin-left: 2rem;
217
+ }
218
+ .assistant-message {
219
+ background: linear-gradient(135deg, #F3E5F5 0%, #E1BEE7 100%);
220
+ border-left: 4px solid #9C27B0;
221
+ margin-right: 2rem;
222
+ }
223
+ .support-ticket {
224
+ background: linear-gradient(135deg, #FFF3E0 0%, #FFCC80 100%);
225
+ padding: 1.5rem;
226
+ border-radius: 0.8rem;
227
+ border-left: 4px solid #FF9800;
228
+ margin: 1rem 0;
229
+ }
230
+ .status-indicator {
231
+ display: inline-block;
232
+ width: 12px;
233
+ height: 12px;
234
+ border-radius: 50%;
235
+ margin-right: 8px;
236
+ }
237
+ .status-open { background-color: #4CAF50; }
238
+ .status-closed { background-color: #F44336; }
239
+ .status-pending { background-color: #FF9800; }
240
+ .metric-card {
241
+ background: white;
242
+ padding: 1rem;
243
+ border-radius: 0.8rem;
244
+ text-align: center;
245
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
246
+ }
247
+ </style>
248
+ """, unsafe_allow_html=True)
249
+
250
+ # Session state initialization
251
+ def initialize_session_state():
252
+ """Initialize session state variables."""
253
+ if 'conversation' not in st.session_state:
254
+ st.session_state.conversation = []
255
+
256
+ if 'support_tickets' not in st.session_state:
257
+ st.session_state.support_tickets = []
258
+
259
+ if 'business_assistant' not in st.session_state:
260
+ st.session_state.business_assistant = None
261
+
262
+ if 'user_session_id' not in st.session_state:
263
+ st.session_state.user_session_id = str(uuid.uuid4())
264
+
265
+ if 'chat_analytics' not in st.session_state:
266
+ st.session_state.chat_analytics = []
267
+
268
+ class BusinessKnowledgeBase:
269
+ """Advanced business knowledge base with intelligent query processing."""
270
+
271
+ def __init__(self, business_info: Dict):
272
+ self.business_info = business_info
273
+ self.knowledge_patterns = self._build_knowledge_patterns()
274
+
275
+ def _build_knowledge_patterns(self) -> Dict[str, Any]:
276
+ """Build patterns for intelligent query matching."""
277
+ return {
278
+ "hours": {
279
+ "keywords": ["hours", "open", "close", "time", "schedule", "when", "operating"],
280
+ "context": "business hours and schedule"
281
+ },
282
+ "location": {
283
+ "keywords": ["location", "address", "where", "directions", "map", "office"],
284
+ "context": "business location and address"
285
+ },
286
+ "contact": {
287
+ "keywords": ["phone", "email", "contact", "call", "reach", "number"],
288
+ "context": "contact information"
289
+ },
290
+ "services": {
291
+ "keywords": ["services", "what", "offer", "do", "provide", "solutions", "products"],
292
+ "context": "services and offerings"
293
+ },
294
+ "team": {
295
+ "keywords": ["team", "staff", "who", "people", "employees", "founders"],
296
+ "context": "team information"
297
+ },
298
+ "support": {
299
+ "keywords": ["support", "help", "assistance", "problem", "issue", "ticket"],
300
+ "context": "support and assistance"
301
+ },
302
+ "pricing": {
303
+ "keywords": ["price", "cost", "pricing", "fee", "rates", "budget"],
304
+ "context": "pricing information"
305
+ }
306
+ }
307
+
308
+ def search_knowledge(self, query: str) -> Dict[str, Any]:
309
+ """Search knowledge base for relevant information."""
310
+ query_lower = query.lower()
311
+ matches = {}
312
+
313
+ for category, pattern in self.knowledge_patterns.items():
314
+ score = sum(1 for keyword in pattern["keywords"] if keyword in query_lower)
315
+ if score > 0:
316
+ matches[category] = {
317
+ "score": score,
318
+ "context": pattern["context"],
319
+ "data": self._get_category_data(category)
320
+ }
321
+
322
+ return dict(sorted(matches.items(), key=lambda x: x[1]["score"], reverse=True))
323
+
324
+ def _get_category_data(self, category: str) -> Any:
325
+ """Get data for a specific category."""
326
+ category_mapping = {
327
+ "hours": self.business_info["hours"],
328
+ "location": self.business_info["location"],
329
+ "contact": self.business_info["contact"],
330
+ "services": self.business_info["services"],
331
+ "team": self.business_info["team"],
332
+ "support": self.business_info["support"],
333
+ "pricing": [service for service in self.business_info["services"]]
334
+ }
335
+ return category_mapping.get(category, {})
336
+
337
+ def generate_business_context(self) -> str:
338
+ """Generate comprehensive business context for AI queries."""
339
+ context_parts = [
340
+ f"Company: {self.business_info['company_name']}",
341
+ f"Description: {self.business_info['description']}",
342
+ f"Location: {self.business_info['location']['address']}, {self.business_info['location']['city']}, {self.business_info['location']['state']}",
343
+ f"Phone: {self.business_info['contact']['phone']}",
344
+ f"Email: {self.business_info['contact']['email']}",
345
+ f"Website: {self.business_info['contact']['website']}",
346
+ "",
347
+ "Business Hours:",
348
+ ]
349
+
350
+ for day, hours in self.business_info["hours"].items():
351
+ if day != "holidays":
352
+ if isinstance(hours, dict):
353
+ context_parts.append(f" {day.title()}: {hours['open']} - {hours['close']} {hours['timezone']}")
354
+ else:
355
+ context_parts.append(f" {day.title()}: {hours}")
356
+
357
+ context_parts.extend([
358
+ "",
359
+ "Services:",
360
+ ])
361
+
362
+ for service in self.business_info["services"]:
363
+ context_parts.append(f" - {service['name']}: {service['description']} (Duration: {service['duration']}, Price: {service['price_range']})")
364
+
365
+ return "\n".join(context_parts)
366
+
367
+ class SupportTicketManager:
368
+ """Advanced support ticket management system."""
369
+
370
+ def __init__(self):
371
+ self.ticket_categories = [
372
+ "General Inquiry",
373
+ "Technical Support",
374
+ "Billing Question",
375
+ "Service Request",
376
+ "Bug Report",
377
+ "Feature Request",
378
+ "Emergency"
379
+ ]
380
+ self.priorities = ["Low", "Medium", "High", "Critical"]
381
+
382
+ def create_ticket(self, title: str, description: str, category: str, priority: str,
383
+ contact_info: Dict, user_session_id: str) -> Dict[str, Any]:
384
+ """Create a new support ticket."""
385
+ ticket = {
386
+ "id": self._generate_ticket_id(),
387
+ "title": title,
388
+ "description": description,
389
+ "category": category,
390
+ "priority": priority,
391
+ "status": "Open",
392
+ "created_at": datetime.now(),
393
+ "updated_at": datetime.now(),
394
+ "contact_info": contact_info,
395
+ "user_session_id": user_session_id,
396
+ "responses": []
397
+ }
398
+
399
+ # Simulate external ticket system integration
400
+ self._integrate_with_external_systems(ticket)
401
+
402
+ return ticket
403
+
404
+ def _generate_ticket_id(self) -> str:
405
+ """Generate unique ticket ID."""
406
+ timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
407
+ random_suffix = hashlib.md5(str(time.time()).encode()).hexdigest()[:6]
408
+ return f"TKT-{timestamp}-{random_suffix.upper()}"
409
+
410
+ def _integrate_with_external_systems(self, ticket: Dict) -> bool:
411
+ """Simulate integration with external ticket systems."""
412
+ try:
413
+ # Simulate GitHub Issues integration
414
+ github_issue = self._create_github_issue(ticket)
415
+
416
+ # Simulate Jira integration
417
+ jira_ticket = self._create_jira_ticket(ticket)
418
+
419
+ # Simulate Trello integration
420
+ trello_card = self._create_trello_card(ticket)
421
+
422
+ ticket["external_integrations"] = {
423
+ "github": github_issue,
424
+ "jira": jira_ticket,
425
+ "trello": trello_card
426
+ }
427
+
428
+ return True
429
+
430
+ except Exception as e:
431
+ st.warning(f"External integration warning: {e}")
432
+ return False
433
+
434
+ def _create_github_issue(self, ticket: Dict) -> Dict:
435
+ """Simulate GitHub issue creation."""
436
+ return {
437
+ "platform": "GitHub",
438
+ "url": f"https://github.com/agentai-solutions/support/issues/{ticket['id']}",
439
+ "issue_number": len(st.session_state.support_tickets) + 1,
440
+ "status": "created",
441
+ "labels": [ticket["category"].lower().replace(" ", "-"), ticket["priority"].lower()]
442
+ }
443
+
444
+ def _create_jira_ticket(self, ticket: Dict) -> Dict:
445
+ """Simulate Jira ticket creation."""
446
+ return {
447
+ "platform": "Jira",
448
+ "url": f"https://agentai-solutions.atlassian.net/browse/{ticket['id']}",
449
+ "key": ticket['id'],
450
+ "status": "Open",
451
+ "project": "SUPPORT"
452
+ }
453
+
454
+ def _create_trello_card(self, ticket: Dict) -> Dict:
455
+ """Simulate Trello card creation."""
456
+ return {
457
+ "platform": "Trello",
458
+ "url": f"https://trello.com/c/{ticket['id'][:8]}",
459
+ "board": "Customer Support",
460
+ "list": "New Tickets",
461
+ "card_id": ticket['id'][:8]
462
+ }
463
+
464
+ class BusinessAIAssistant:
465
+ """Advanced AI-powered business assistant."""
466
+
467
+ def __init__(self):
468
+ self.knowledge_base = BusinessKnowledgeBase(BUSINESS_INFO)
469
+ self.ticket_manager = SupportTicketManager()
470
+
471
+ if STREAMING_AVAILABLE:
472
+ try:
473
+ self.streaming_system = AdvancedStreamingSystem()
474
+ self.ai_available = True
475
+ except Exception as e:
476
+ st.warning(f"AI streaming not available: {e}")
477
+ self.ai_available = False
478
+ else:
479
+ self.ai_available = False
480
+
481
+ def process_query(self, query: str, use_ai: bool = True) -> Dict[str, Any]:
482
+ """Process user query with knowledge base and AI assistance."""
483
+ # Search knowledge base
484
+ knowledge_matches = self.knowledge_base.search_knowledge(query)
485
+
486
+ # Determine if AI assistance is needed
487
+ if use_ai and self.ai_available and knowledge_matches:
488
+ ai_response = self._get_ai_response(query, knowledge_matches)
489
+ return {
490
+ "type": "ai_enhanced",
491
+ "response": ai_response,
492
+ "knowledge_matches": knowledge_matches,
493
+ "confidence": "high"
494
+ }
495
+ elif knowledge_matches:
496
+ structured_response = self._create_structured_response(knowledge_matches)
497
+ return {
498
+ "type": "knowledge_base",
499
+ "response": structured_response,
500
+ "knowledge_matches": knowledge_matches,
501
+ "confidence": "medium"
502
+ }
503
+ else:
504
+ return {
505
+ "type": "unknown",
506
+ "response": "I don't have specific information about that. Would you like to create a support ticket for assistance?",
507
+ "knowledge_matches": {},
508
+ "confidence": "low"
509
+ }
510
+
511
+ def _get_ai_response(self, query: str, knowledge_matches: Dict) -> str:
512
+ """Get AI-enhanced response using streaming system."""
513
+ try:
514
+ # Create context-aware prompt
515
+ business_context = self.knowledge_base.generate_business_context()
516
+
517
+ # Prepare AI messages
518
+ messages = [
519
+ {
520
+ "role": "system",
521
+ "content": f"""You are a professional business assistant for {BUSINESS_INFO['company_name']}.
522
+
523
+ Business Information:
524
+ {business_context}
525
+
526
+ Instructions:
527
+ - Provide accurate, helpful information about the business
528
+ - Be professional and friendly
529
+ - If you don't have specific information, acknowledge it and suggest contacting support
530
+ - Keep responses concise but comprehensive
531
+ - Use business hours, contact info, and services from the provided context"""
532
+ },
533
+ {
534
+ "role": "user",
535
+ "content": query
536
+ }
537
+ ]
538
+
539
+ # Use the first available provider
540
+ if self.streaming_system.streamers:
541
+ provider = list(self.streaming_system.streamers.keys())[0]
542
+ config = StreamingConfig(
543
+ model="gpt-4o" if provider.value == "openai" else "gemini-1.5-flash",
544
+ temperature=0.3,
545
+ max_tokens=500
546
+ )
547
+
548
+ response = self.streaming_system.stream_with_display(messages, provider, config)
549
+ return response.content
550
+
551
+ except Exception as e:
552
+ st.warning(f"AI response error: {e}")
553
+
554
+ # Fallback to structured response
555
+ return self._create_structured_response(knowledge_matches)
556
+
557
+ def _create_structured_response(self, knowledge_matches: Dict) -> str:
558
+ """Create structured response from knowledge base matches."""
559
+ if not knowledge_matches:
560
+ return "I don't have specific information about that. Please contact our support team for assistance."
561
+
562
+ response_parts = []
563
+
564
+ for category, match in list(knowledge_matches.items())[:2]: # Top 2 matches
565
+ data = match["data"]
566
+
567
+ if category == "hours":
568
+ response_parts.append("πŸ“… **Business Hours:**")
569
+ for day, hours in data.items():
570
+ if day != "holidays":
571
+ if isinstance(hours, dict):
572
+ response_parts.append(f" β€’ {day.title()}: {hours['open']} - {hours['close']} {hours['timezone']}")
573
+ else:
574
+ response_parts.append(f" β€’ {day.title()}: {hours}")
575
+
576
+ elif category == "location":
577
+ response_parts.append(f"πŸ“ **Location:**")
578
+ response_parts.append(f" β€’ Address: {data['address']}")
579
+ response_parts.append(f" β€’ City: {data['city']}, {data['state']} {data['zip']}")
580
+ response_parts.append(f" β€’ Timezone: {data['timezone']}")
581
+
582
+ elif category == "contact":
583
+ response_parts.append("πŸ“ž **Contact Information:**")
584
+ response_parts.append(f" β€’ Phone: {data['phone']}")
585
+ response_parts.append(f" β€’ Email: {data['email']}")
586
+ response_parts.append(f" β€’ Website: {data['website']}")
587
+
588
+ elif category == "services":
589
+ response_parts.append("πŸ’Ό **Our Services:**")
590
+ for service in data[:3]: # Top 3 services
591
+ response_parts.append(f" β€’ **{service['name']}**: {service['description']}")
592
+
593
+ response_parts.append("") # Add spacing
594
+
595
+ return "\n".join(response_parts)
596
+
597
+ def display_business_header():
598
+ """Display business header with key information."""
599
+ st.markdown(f'<h1 class="main-header">🏒 {BUSINESS_INFO["company_name"]}</h1>', unsafe_allow_html=True)
600
+ st.markdown(f'<p class="sub-header">{BUSINESS_INFO["tagline"]}</p>', unsafe_allow_html=True)
601
+
602
+ # Business card
603
+ st.markdown(f"""
604
+ <div class="business-card">
605
+ <h3>πŸ“ Quick Info</h3>
606
+ <p><strong>πŸ“ž Phone:</strong> {BUSINESS_INFO["contact"]["phone"]}</p>
607
+ <p><strong>πŸ“§ Email:</strong> {BUSINESS_INFO["contact"]["email"]}</p>
608
+ <p><strong>🌐 Website:</strong> {BUSINESS_INFO["contact"]["website"]}</p>
609
+ <p><strong>πŸ“ Location:</strong> {BUSINESS_INFO["location"]["city"]}, {BUSINESS_INFO["location"]["state"]}</p>
610
+ </div>
611
+ """, unsafe_allow_html=True)
612
+
613
+ def display_business_status():
614
+ """Display current business status and metrics."""
615
+ col1, col2, col3, col4 = st.columns(4)
616
+
617
+ with col1:
618
+ st.markdown("""
619
+ <div class="metric-card">
620
+ <h4>πŸ• Status</h4>
621
+ <span class="status-indicator status-open"></span>
622
+ <strong>Open Now</strong>
623
+ </div>
624
+ """, unsafe_allow_html=True)
625
+
626
+ with col2:
627
+ st.markdown("""
628
+ <div class="metric-card">
629
+ <h4>⏱️ Response Time</h4>
630
+ <strong>< 24 hours</strong>
631
+ </div>
632
+ """, unsafe_allow_html=True)
633
+
634
+ with col3:
635
+ ticket_count = len(st.session_state.support_tickets)
636
+ st.markdown(f"""
637
+ <div class="metric-card">
638
+ <h4>🎫 Active Tickets</h4>
639
+ <strong>{ticket_count}</strong>
640
+ </div>
641
+ """, unsafe_allow_html=True)
642
+
643
+ with col4:
644
+ st.markdown("""
645
+ <div class="metric-card">
646
+ <h4>πŸ€– AI Status</h4>
647
+ <strong>Online</strong>
648
+ </div>
649
+ """, unsafe_allow_html=True)
650
+
651
+ def create_sidebar():
652
+ """Create sidebar with navigation and options."""
653
+ st.sidebar.title("🏒 Business Assistant")
654
+
655
+ # Navigation
656
+ page = st.sidebar.selectbox(
657
+ "πŸ“‹ Navigate",
658
+ ["πŸ’¬ Chat Assistant", "🎫 Support Tickets", "πŸ“Š Business Info", "βš™οΈ Settings"]
659
+ )
660
+
661
+ # Quick actions
662
+ st.sidebar.markdown("### πŸš€ Quick Actions")
663
+
664
+ if st.sidebar.button("πŸ“ž Call Now", use_container_width=True):
665
+ st.sidebar.success(f"Call: {BUSINESS_INFO['contact']['phone']}")
666
+
667
+ if st.sidebar.button("πŸ“§ Send Email", use_container_width=True):
668
+ st.sidebar.success(f"Email: {BUSINESS_INFO['contact']['email']}")
669
+
670
+ if st.sidebar.button("🌐 Visit Website", use_container_width=True):
671
+ st.sidebar.success(f"Website: {BUSINESS_INFO['contact']['website']}")
672
+
673
+ # Business hours
674
+ st.sidebar.markdown("### πŸ• Today's Hours")
675
+ current_day = datetime.now().strftime("%A").lower()
676
+ today_hours = BUSINESS_INFO["hours"].get(current_day, "Closed")
677
+
678
+ if isinstance(today_hours, dict):
679
+ st.sidebar.info(f"**{current_day.title()}:** {today_hours['open']} - {today_hours['close']}")
680
+ else:
681
+ st.sidebar.info(f"**{current_day.title()}:** {today_hours}")
682
+
683
+ return page
684
+
685
+ def chat_assistant_page():
686
+ """Main chat assistant interface."""
687
+ st.markdown("### πŸ’¬ Business Assistant Chat")
688
+ st.markdown("Ask me anything about our business - hours, location, services, or contact information!")
689
+
690
+ # Initialize assistant
691
+ if st.session_state.business_assistant is None:
692
+ st.session_state.business_assistant = BusinessAIAssistant()
693
+
694
+ assistant = st.session_state.business_assistant
695
+
696
+ # Display conversation
697
+ for message in st.session_state.conversation:
698
+ if message["role"] == "user":
699
+ st.markdown(f"""
700
+ <div class="chat-message user-message">
701
+ <strong>πŸ‘€ You:</strong><br>
702
+ {message["content"]}
703
+ </div>
704
+ """, unsafe_allow_html=True)
705
+ else:
706
+ st.markdown(f"""
707
+ <div class="chat-message assistant-message">
708
+ <strong>πŸ€– Assistant:</strong><br>
709
+ {message["content"]}
710
+ </div>
711
+ """, unsafe_allow_html=True)
712
+
713
+ # Chat input
714
+ with st.form("chat_form", clear_on_submit=True):
715
+ user_input = st.text_area(
716
+ "Your question:",
717
+ placeholder="Ask about our hours, location, services, contact info...",
718
+ height=100
719
+ )
720
+
721
+ col1, col2, col3 = st.columns([2, 1, 1])
722
+
723
+ with col1:
724
+ send_button = st.form_submit_button("πŸš€ Send", use_container_width=True)
725
+
726
+ with col2:
727
+ ai_enabled = st.form_submit_button("πŸ€– AI Mode", use_container_width=True)
728
+
729
+ with col3:
730
+ clear_button = st.form_submit_button("πŸ—‘οΈ Clear", use_container_width=True)
731
+
732
+ # Process input
733
+ if (send_button or ai_enabled) and user_input.strip():
734
+ # Add user message
735
+ st.session_state.conversation.append({
736
+ "role": "user",
737
+ "content": user_input.strip()
738
+ })
739
+
740
+ # Process query
741
+ with st.spinner("πŸ€– Processing your question..."):
742
+ response_data = assistant.process_query(user_input.strip(), use_ai=ai_enabled)
743
+
744
+ # Add assistant response
745
+ st.session_state.conversation.append({
746
+ "role": "assistant",
747
+ "content": response_data["response"]
748
+ })
749
+
750
+ # Show confidence and suggest ticket if needed
751
+ if response_data["confidence"] == "low":
752
+ st.warning("⚠️ I couldn't find specific information about that. Would you like to create a support ticket?")
753
+ if st.button("🎫 Create Support Ticket"):
754
+ st.session_state.pending_ticket_query = user_input.strip()
755
+ st.rerun()
756
+
757
+ st.rerun()
758
+
759
+ if clear_button:
760
+ st.session_state.conversation = []
761
+ st.rerun()
762
+
763
+ def support_tickets_page():
764
+ """Support ticket management interface."""
765
+ st.markdown("### 🎫 Support Ticket System")
766
+
767
+ tab1, tab2 = st.tabs(["πŸ“ Create Ticket", "πŸ“‹ My Tickets"])
768
+
769
+ with tab1:
770
+ st.markdown("#### Create New Support Ticket")
771
+
772
+ if st.session_state.business_assistant is None:
773
+ st.session_state.business_assistant = BusinessAIAssistant()
774
+
775
+ ticket_manager = st.session_state.business_assistant.ticket_manager
776
+
777
+ with st.form("create_ticket_form"):
778
+ col1, col2 = st.columns(2)
779
+
780
+ with col1:
781
+ title = st.text_input("Ticket Title*", placeholder="Brief description of your issue")
782
+ category = st.selectbox("Category*", ticket_manager.ticket_categories)
783
+ priority = st.selectbox("Priority*", ticket_manager.priorities)
784
+
785
+ with col2:
786
+ name = st.text_input("Your Name*", placeholder="Full name")
787
+ email = st.text_input("Email*", placeholder="[email protected]")
788
+ phone = st.text_input("Phone", placeholder="Optional phone number")
789
+
790
+ description = st.text_area(
791
+ "Description*",
792
+ placeholder="Detailed description of your issue or request...",
793
+ height=150
794
+ )
795
+
796
+ # Pre-fill if coming from chat
797
+ if hasattr(st.session_state, 'pending_ticket_query'):
798
+ description = st.text_area(
799
+ "Description*",
800
+ value=st.session_state.pending_ticket_query,
801
+ height=150
802
+ )
803
+ del st.session_state.pending_ticket_query
804
+
805
+ submit_ticket = st.form_submit_button("🎫 Create Ticket", use_container_width=True)
806
+
807
+ if submit_ticket:
808
+ if title and description and name and email and category and priority:
809
+ # Create ticket
810
+ contact_info = {"name": name, "email": email, "phone": phone}
811
+
812
+ ticket = ticket_manager.create_ticket(
813
+ title, description, category, priority,
814
+ contact_info, st.session_state.user_session_id
815
+ )
816
+
817
+ # Add to session
818
+ st.session_state.support_tickets.append(ticket)
819
+
820
+ # Display success
821
+ st.success(f"βœ… Ticket created successfully!")
822
+ st.markdown(f"""
823
+ <div class="support-ticket">
824
+ <h4>🎫 Ticket #{ticket['id']}</h4>
825
+ <p><strong>Status:</strong> <span class="status-indicator status-open"></span> {ticket['status']}</p>
826
+ <p><strong>Priority:</strong> {ticket['priority']}</p>
827
+ <p><strong>Category:</strong> {ticket['category']}</p>
828
+ <p><strong>Created:</strong> {ticket['created_at'].strftime('%Y-%m-%d %H:%M:%S')}</p>
829
+
830
+ <h5>External Integrations:</h5>
831
+ <ul>
832
+ <li>πŸ“š GitHub: <a href="{ticket['external_integrations']['github']['url']}" target="_blank">Issue #{ticket['external_integrations']['github']['issue_number']}</a></li>
833
+ <li>πŸ”§ Jira: <a href="{ticket['external_integrations']['jira']['url']}" target="_blank">{ticket['external_integrations']['jira']['key']}</a></li>
834
+ <li>πŸ“‹ Trello: <a href="{ticket['external_integrations']['trello']['url']}" target="_blank">Card {ticket['external_integrations']['trello']['card_id']}</a></li>
835
+ </ul>
836
+
837
+ <p><strong>Expected Response:</strong> {BUSINESS_INFO['support']['response_time']}</p>
838
+ <p>You will receive updates at: <strong>{email}</strong></p>
839
+ </div>
840
+ """, unsafe_allow_html=True)
841
+
842
+ else:
843
+ st.error("❌ Please fill in all required fields marked with *")
844
+
845
+ with tab2:
846
+ st.markdown("#### Your Support Tickets")
847
+
848
+ if st.session_state.support_tickets:
849
+ for ticket in reversed(st.session_state.support_tickets): # Most recent first
850
+ status_class = f"status-{ticket['status'].lower()}"
851
+
852
+ st.markdown(f"""
853
+ <div class="support-ticket">
854
+ <h4>🎫 {ticket['title']}</h4>
855
+ <p><strong>ID:</strong> {ticket['id']}</p>
856
+ <p><strong>Status:</strong> <span class="status-indicator {status_class}"></span> {ticket['status']}</p>
857
+ <p><strong>Priority:</strong> {ticket['priority']} | <strong>Category:</strong> {ticket['category']}</p>
858
+ <p><strong>Created:</strong> {ticket['created_at'].strftime('%Y-%m-%d %H:%M:%S')}</p>
859
+ <p><strong>Description:</strong> {ticket['description'][:200]}...</p>
860
+ </div>
861
+ """, unsafe_allow_html=True)
862
+ else:
863
+ st.info("πŸ“ No support tickets yet. Create one above if you need assistance!")
864
+
865
+ def business_info_page():
866
+ """Business information dashboard."""
867
+ st.markdown("### πŸ“Š Business Information")
868
+
869
+ tab1, tab2, tab3, tab4 = st.tabs(["🏒 Overview", "πŸ• Hours", "πŸ’Ό Services", "πŸ‘₯ Team"])
870
+
871
+ with tab1:
872
+ st.markdown("#### Company Overview")
873
+
874
+ col1, col2 = st.columns(2)
875
+
876
+ with col1:
877
+ st.markdown(f"""
878
+ <div class="info-card">
879
+ <h4>🏒 {BUSINESS_INFO['company_name']}</h4>
880
+ <p><strong>Description:</strong> {BUSINESS_INFO['description']}</p>
881
+ <p><strong>Tagline:</strong> {BUSINESS_INFO['tagline']}</p>
882
+ </div>
883
+ """, unsafe_allow_html=True)
884
+
885
+ st.markdown(f"""
886
+ <div class="info-card">
887
+ <h4>πŸ“ Location</h4>
888
+ <p><strong>Address:</strong> {BUSINESS_INFO['location']['address']}</p>
889
+ <p><strong>City:</strong> {BUSINESS_INFO['location']['city']}, {BUSINESS_INFO['location']['state']} {BUSINESS_INFO['location']['zip']}</p>
890
+ <p><strong>Country:</strong> {BUSINESS_INFO['location']['country']}</p>
891
+ <p><strong>Timezone:</strong> {BUSINESS_INFO['location']['timezone']}</p>
892
+ </div>
893
+ """, unsafe_allow_html=True)
894
+
895
+ with col2:
896
+ st.markdown(f"""
897
+ <div class="info-card">
898
+ <h4>πŸ“ž Contact Information</h4>
899
+ <p><strong>Phone:</strong> {BUSINESS_INFO['contact']['phone']}</p>
900
+ <p><strong>Email:</strong> {BUSINESS_INFO['contact']['email']}</p>
901
+ <p><strong>Support Email:</strong> {BUSINESS_INFO['contact']['support_email']}</p>
902
+ <p><strong>Website:</strong> <a href="{BUSINESS_INFO['contact']['website']}" target="_blank">{BUSINESS_INFO['contact']['website']}</a></p>
903
+ <p><strong>LinkedIn:</strong> <a href="{BUSINESS_INFO['contact']['linkedin']}" target="_blank">Company Profile</a></p>
904
+ </div>
905
+ """, unsafe_allow_html=True)
906
+
907
+ st.markdown(f"""
908
+ <div class="info-card">
909
+ <h4>🎯 Support Information</h4>
910
+ <p><strong>Response Time:</strong> {BUSINESS_INFO['support']['response_time']}</p>
911
+ <p><strong>Channels:</strong> {', '.join(BUSINESS_INFO['support']['channels'])}</p>
912
+ <p><strong>Emergency:</strong> {BUSINESS_INFO['support']['emergency_contact']}</p>
913
+ </div>
914
+ """, unsafe_allow_html=True)
915
+
916
+ with tab2:
917
+ st.markdown("#### Business Hours")
918
+
919
+ hours_data = []
920
+ for day, hours in BUSINESS_INFO["hours"].items():
921
+ if day != "holidays":
922
+ if isinstance(hours, dict):
923
+ hours_data.append({
924
+ "Day": day.title(),
925
+ "Open": hours["open"],
926
+ "Close": hours["close"],
927
+ "Timezone": hours["timezone"]
928
+ })
929
+ else:
930
+ hours_data.append({
931
+ "Day": day.title(),
932
+ "Open": hours,
933
+ "Close": "",
934
+ "Timezone": ""
935
+ })
936
+
937
+ st.table(hours_data)
938
+
939
+ st.info(f"πŸŽ„ Holiday Hours: {BUSINESS_INFO['hours']['holidays']}")
940
+
941
+ with tab3:
942
+ st.markdown("#### Our Services")
943
+
944
+ for service in BUSINESS_INFO["services"]:
945
+ st.markdown(f"""
946
+ <div class="info-card">
947
+ <h4>πŸ’Ό {service['name']}</h4>
948
+ <p><strong>Description:</strong> {service['description']}</p>
949
+ <p><strong>Duration:</strong> {service['duration']}</p>
950
+ <p><strong>Price Range:</strong> {service['price_range']}</p>
951
+ </div>
952
+ """, unsafe_allow_html=True)
953
+
954
+ with tab4:
955
+ st.markdown("#### Our Team")
956
+
957
+ cols = st.columns(2)
958
+ for i, member in enumerate(BUSINESS_INFO["team"]):
959
+ with cols[i % 2]:
960
+ st.markdown(f"""
961
+ <div class="info-card">
962
+ <h4>πŸ‘€ {member['name']}</h4>
963
+ <p><strong>Role:</strong> {member['role']}</p>
964
+ <p><strong>Expertise:</strong> {member['expertise']}</p>
965
+ </div>
966
+ """, unsafe_allow_html=True)
967
+
968
+ def settings_page():
969
+ """Settings and configuration page."""
970
+ st.markdown("### βš™οΈ Settings")
971
+
972
+ col1, col2 = st.columns(2)
973
+
974
+ with col1:
975
+ st.markdown("#### πŸ€– AI Configuration")
976
+
977
+ ai_enabled = st.checkbox("Enable AI Responses", value=True)
978
+ ai_provider = st.selectbox("AI Provider", ["Auto", "OpenAI", "Gemini", "Hugging Face"])
979
+ response_length = st.slider("Response Length", 100, 1000, 500)
980
+
981
+ st.markdown("#### 🎫 Ticket Settings")
982
+ auto_ticket = st.checkbox("Auto-suggest tickets for unknown queries", value=True)
983
+ email_notifications = st.checkbox("Email notifications", value=True)
984
+
985
+ with col2:
986
+ st.markdown("#### πŸ“Š Analytics")
987
+
988
+ st.metric("Total Conversations", len(st.session_state.conversation))
989
+ st.metric("Support Tickets Created", len(st.session_state.support_tickets))
990
+ st.metric("Session ID", st.session_state.user_session_id[:8] + "...")
991
+
992
+ st.markdown("#### πŸ”„ Actions")
993
+
994
+ if st.button("πŸ—‘οΈ Clear All Data", use_container_width=True):
995
+ st.session_state.conversation = []
996
+ st.session_state.support_tickets = []
997
+ st.session_state.chat_analytics = []
998
+ st.success("βœ… All data cleared!")
999
+
1000
+ if st.button("πŸ’Ύ Export Data", use_container_width=True):
1001
+ export_data = {
1002
+ "conversation": st.session_state.conversation,
1003
+ "support_tickets": [
1004
+ {**ticket, "created_at": ticket["created_at"].isoformat(),
1005
+ "updated_at": ticket["updated_at"].isoformat()}
1006
+ for ticket in st.session_state.support_tickets
1007
+ ],
1008
+ "analytics": st.session_state.chat_analytics,
1009
+ "session_id": st.session_state.user_session_id,
1010
+ "export_timestamp": datetime.now().isoformat()
1011
+ }
1012
+
1013
+ st.download_button(
1014
+ label="πŸ“₯ Download JSON",
1015
+ data=json.dumps(export_data, indent=2),
1016
+ file_name=f"business_assistant_data_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
1017
+ mime="application/json"
1018
+ )
1019
+
1020
+ def main():
1021
+ """Main Streamlit application."""
1022
+ # Initialize session state
1023
+ initialize_session_state()
1024
+
1025
+ # Display header
1026
+ display_business_header()
1027
+
1028
+ # Display status
1029
+ display_business_status()
1030
+
1031
+ # Create sidebar and get current page
1032
+ current_page = create_sidebar()
1033
+
1034
+ # Display appropriate page
1035
+ st.markdown("---")
1036
+
1037
+ if current_page == "πŸ’¬ Chat Assistant":
1038
+ chat_assistant_page()
1039
+ elif current_page == "🎫 Support Tickets":
1040
+ support_tickets_page()
1041
+ elif current_page == "πŸ“Š Business Info":
1042
+ business_info_page()
1043
+ elif current_page == "βš™οΈ Settings":
1044
+ settings_page()
1045
+
1046
+ # Footer
1047
+ st.markdown("---")
1048
+ st.markdown(
1049
+ f"πŸš€ **{BUSINESS_INFO['company_name']}** | "
1050
+ f"πŸ“ž {BUSINESS_INFO['contact']['phone']} | "
1051
+ f"πŸ“§ {BUSINESS_INFO['contact']['email']} | "
1052
+ f"Powered by Advanced AI & Hugging Face Spaces"
1053
+ )
1054
+
1055
+ if __name__ == "__main__":
1056
+ main()