Yordann commited on
Commit
e2fb53f
·
verified ·
1 Parent(s): 97986d7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +55 -132
app.py CHANGED
@@ -1,84 +1,21 @@
1
  import gradio as gr
2
- from transformers import pipeline, AutoTokenizer
3
- from transformers import AutoModelForCausalLM
4
  from langdetect import detect
5
- from huggingface_hub import login
6
  import os
7
- import base64
8
  from PIL import Image
9
  from transformers import BlipProcessor, BlipForConditionalGeneration
10
  import requests
11
  from bs4 import BeautifulSoup
12
  import cv2
13
- from io import BytesIO
14
  import torch
15
- from sentence_transformers import SentenceTransformer
16
- import numpy as np
17
- import faiss
18
 
 
 
19
 
20
- login(token=os.getenv("chatbot"))
21
- generator = pipeline("text-generation", model="mistralai/Mistral-7B-Instruct-v0.1")
22
  bg_to_en = pipeline("translation", model="Helsinki-NLP/opus-mt-bg-en")
23
  en_to_bg = pipeline("translation", model="Helsinki-NLP/opus-mt-en-bg")
24
- tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-Instruct-v0.1")
25
-
26
- def load_chunks(path, chunk_size=300):
27
- with open(path, "r", encoding="utf-8") as f:
28
- text = f.read()
29
-
30
- sentences = text.split(". ")
31
- chunks, chunk = [], ""
32
-
33
- for sentence in sentences:
34
- if len(chunk.split()) + len(sentence.split()) < chunk_size:
35
- chunk += sentence + ". "
36
- else:
37
- chunks.append(chunk.strip())
38
- chunk = sentence + ". "
39
-
40
- if chunk:
41
- chunks.append(chunk.strip())
42
-
43
- return chunks
44
-
45
- # Load your document chunks
46
- chunks = load_chunks("MasterBrand Explanation.txt")
47
-
48
- # Create embeddings
49
- embedding_model = SentenceTransformer("all-MiniLM-L6-v2")
50
- embeddings = embedding_model.encode(chunks)
51
-
52
- # Build FAISS index
53
- dimension = embeddings[0].shape[0]
54
- index = faiss.IndexFlatL2(dimension)
55
- index.add(np.array(embeddings))
56
-
57
- def search_similar_chunks(query, k=3):
58
- query_embedding = embedding_model.encode([query])
59
- distances, indices = index.search(np.array(query_embedding), k)
60
- return [chunks[i] for i in indices[0]]
61
-
62
- def generate_answer_with_context(question):
63
- top_chunks = search_similar_chunks(question)
64
- context = "\n\n".join(top_chunks)
65
-
66
- prompt = f"""<s>
67
- You are a helpful assistant trained on e-commerce and branding content.
68
-
69
- Use the context below to answer the question.
70
-
71
- Context:
72
- {context}
73
-
74
- Question: {question}
75
- Answer:"""
76
-
77
- inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
78
- outputs = model.generate(**inputs, max_new_tokens=300)
79
- response = tokenizer.decode(outputs[0], skip_special_tokens=True)
80
-
81
- return response.replace(prompt, "").strip()
82
 
83
  # Load BLIP for image captioning
84
  blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
@@ -86,12 +23,14 @@ blip_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image
86
  blip_model.to("cuda" if torch.cuda.is_available() else "cpu")
87
 
88
  def describe_image(image):
 
89
  inputs = blip_processor(images=image, return_tensors="pt").to(blip_model.device)
90
  out = blip_model.generate(**inputs)
91
  caption = blip_processor.decode(out[0], skip_special_tokens=True)
92
  return caption
93
 
94
  def describe_video(video_path):
 
95
  cap = cv2.VideoCapture(video_path)
96
  success, frame = cap.read()
97
  cap.release()
@@ -102,6 +41,7 @@ def describe_video(video_path):
102
  return "Could not read video frame."
103
 
104
  def extract_text_from_url(url):
 
105
  try:
106
  response = requests.get(url, timeout=5)
107
  soup = BeautifulSoup(response.text, 'html.parser')
@@ -111,7 +51,24 @@ def extract_text_from_url(url):
111
  except Exception as e:
112
  return f"Failed to fetch URL: {str(e)}"
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  def generate_response(user_input, top_p, temperature, chat_counter, chatbot, history, image=None, video=None, url=None, request: gr.Request = None):
 
115
  lang = detect(user_input)
116
  print(f"Detected language: {lang}")
117
 
@@ -121,39 +78,44 @@ def generate_response(user_input, top_p, temperature, chat_counter, chatbot, his
121
  else:
122
  user_input_translated = user_input
123
 
124
- prompt = ""
125
-
126
- top_chunks = search_similar_chunks(user_input_translated)
127
- rag_context = "\n\n".join(top_chunks)
128
-
129
- prompt += f"[Context from your e-commerce training document]:\n{rag_context}\n\n"
 
 
130
 
 
 
131
 
132
  # Multimodal additions
133
  if image is not None:
134
  try:
135
  img_desc = describe_image(image)
136
- prompt += f"[Image Description]: {img_desc}\n"
137
  except Exception as e:
138
- prompt += f"[Image Error]: {str(e)}\n"
139
 
140
  if video is not None:
141
  try:
142
  vid_desc = describe_video(video)
143
- prompt += f"[Video Description]: {vid_desc}\n"
144
  except Exception as e:
145
- prompt += f"[Video Error]: {str(e)}\n"
146
 
147
  if url:
148
  url_content = extract_text_from_url(url)
149
- prompt += f"[URL Content]: {url_content}\n"
150
 
151
- # Append user message to prompt
152
- prompt += f"User said:\n{user_input_translated}\n\nGive simple, friendly, clear advice:\n"
153
 
154
- # Generate response
155
- response_text = generator(prompt, max_length=200, top_p=top_p, temperature=temperature, do_sample=True)[0]["generated_text"]
156
 
 
157
  if lang == "bg":
158
  response_text = en_to_bg(response_text)[0]["translation_text"]
159
 
@@ -165,21 +127,19 @@ def generate_response(user_input, top_p, temperature, chat_counter, chatbot, his
165
  return history, history, chat_counter, "✅ Success", gr.update(value=''), gr.update(interactive=True)
166
 
167
  def reset_textbox():
 
168
  return gr.update(value='')
169
 
170
  # ==== Enhanced Custom CSS with Masterbrand Styling ====
171
  custom_css = f"""
172
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
173
-
174
  * {{
175
  font-family: 'Inter', sans-serif !important;
176
  }}
177
-
178
  .gradio-container {{
179
  background: linear-gradient(135deg, #0a0a0a 0%, #1a0a0a 50%, #2a1a1a 100%) !important;
180
  min-height: 100vh !important;
181
  }}
182
-
183
  .main-header {{
184
  background: linear-gradient(135deg, #0a0a0a 0%, #1a0a0a 50%, #2a1a1a 100%) !important;
185
  padding: 2rem 0 3rem 0 !important;
@@ -189,7 +149,6 @@ custom_css = f"""
189
  position: relative !important;
190
  overflow: hidden !important;
191
  }}
192
-
193
  .main-header::before {{
194
  content: '';
195
  position: absolute;
@@ -200,7 +159,6 @@ custom_css = f"""
200
  background: radial-gradient(circle at 50% 50%, rgba(255, 0, 0, 0.1) 0%, transparent 70%);
201
  pointer-events: none;
202
  }}
203
-
204
  .logo-container {{
205
  display: flex !important;
206
  justify-content: center !important;
@@ -208,7 +166,6 @@ custom_css = f"""
208
  margin-bottom: 1.5rem !important;
209
  gap: 1rem !important;
210
  }}
211
-
212
  .logo-image {{
213
  width: 50px !important;
214
  height: 50px !important;
@@ -217,11 +174,9 @@ custom_css = f"""
217
  animation: pulse-glow 2s ease-in-out infinite alternate !important;
218
  transition: transform 0.3s ease !important;
219
  }}
220
-
221
  .logo-image:hover {{
222
  transform: scale(1.1) !important;
223
  }}
224
-
225
  .brand-text {{
226
  background: linear-gradient(135deg, #00ff41 0%, #ffffff 50%, #ff0000 100%) !important;
227
  -webkit-background-clip: text !important;
@@ -232,7 +187,6 @@ custom_css = f"""
232
  letter-spacing: 2px !important;
233
  text-shadow: 0 0 20px rgba(0, 255, 65, 0.3) !important;
234
  }}
235
-
236
  .main-header h1 {{
237
  color: #ffffff !important;
238
  font-size: 3.5rem !important;
@@ -244,14 +198,12 @@ custom_css = f"""
244
  background-clip: text !important;
245
  margin: 0 !important;
246
  }}
247
-
248
  .main-header p {{
249
  color: #cccccc !important;
250
  font-size: 1.3rem !important;
251
  font-weight: 500 !important;
252
  margin-top: 0.5rem !important;
253
  }}
254
-
255
  .chatbot-container {{
256
  background: rgba(26, 26, 26, 0.95) !important;
257
  border: 2px solid #ff0000 !important;
@@ -260,7 +212,6 @@ custom_css = f"""
260
  margin-bottom: 2rem !important;
261
  backdrop-filter: blur(10px) !important;
262
  }}
263
-
264
  .input-section {{
265
  background: rgba(26, 26, 26, 0.8) !important;
266
  border: 2px solid #333333 !important;
@@ -271,20 +222,16 @@ custom_css = f"""
271
  backdrop-filter: blur(10px) !important;
272
  transition: all 0.3s ease !important;
273
  }}
274
-
275
  .input-section:hover {{
276
  border-color: #ff0000 !important;
277
  box-shadow: 0 15px 40px rgba(255, 0, 0, 0.2) !important;
278
  }}
279
-
280
  .input-group {{
281
  margin-bottom: 1.5rem !important;
282
  }}
283
-
284
  .input-group:last-child {{
285
  margin-bottom: 0 !important;
286
  }}
287
-
288
  .input-label {{
289
  color: #ffffff !important;
290
  font-size: 1.1rem !important;
@@ -294,12 +241,10 @@ custom_css = f"""
294
  align-items: center !important;
295
  gap: 0.5rem !important;
296
  }}
297
-
298
  .input-icon {{
299
  font-size: 1.2rem !important;
300
  color: #ff0000 !important;
301
  }}
302
-
303
  .enhanced-textbox textarea {{
304
  background: linear-gradient(135deg, #1a1a1a 0%, #2a2a1a 100%) !important;
305
  border: 2px solid #444444 !important;
@@ -311,19 +256,16 @@ custom_css = f"""
311
  transition: all 0.3s ease !important;
312
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3) !important;
313
  }}
314
-
315
  .enhanced-textbox textarea:focus {{
316
  border-color: #ff0000 !important;
317
  box-shadow: 0 0 25px rgba(255, 0, 0, 0.4), 0 5px 15px rgba(0, 0, 0, 0.3) !important;
318
  outline: none !important;
319
  transform: translateY(-2px) !important;
320
  }}
321
-
322
  .enhanced-textbox textarea::placeholder {{
323
  color: #888888 !important;
324
  font-style: italic !important;
325
  }}
326
-
327
  .enhanced-image-input, .enhanced-video-input {{
328
  background: rgba(42, 42, 42, 0.8) !important;
329
  border: 2px dashed #444444 !important;
@@ -336,12 +278,10 @@ custom_css = f"""
336
  align-items: center !important;
337
  justify-content: center !important;
338
  }}
339
-
340
  .enhanced-image-input:hover, .enhanced-video-input:hover {{
341
  border-color: #ff0000 !important;
342
  background: rgba(255, 0, 0, 0.05) !important;
343
  }}
344
-
345
  .enhanced-url-input input {{
346
  background: linear-gradient(135deg, #1a1a1a 0%, #2a2a1a 100%) !important;
347
  border: 2px solid #444444 !important;
@@ -352,19 +292,16 @@ custom_css = f"""
352
  transition: all 0.3s ease !important;
353
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3) !important;
354
  }}
355
-
356
  .enhanced-url-input input:focus {{
357
  border-color: #ff0000 !important;
358
  box-shadow: 0 0 25px rgba(255, 0, 0, 0.4), 0 5px 15px rgba(0, 0, 0, 0.3) !important;
359
  outline: none !important;
360
  transform: translateY(-2px) !important;
361
  }}
362
-
363
  .enhanced-url-input input::placeholder {{
364
  color: #888888 !important;
365
  font-style: italic !important;
366
  }}
367
-
368
  .submit-button {{
369
  background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%) !important;
370
  border: none !important;
@@ -380,34 +317,28 @@ custom_css = f"""
380
  width: 100% !important;
381
  margin-top: 1rem !important;
382
  }}
383
-
384
  .submit-button:hover {{
385
  background: linear-gradient(135deg, #cc0000 0%, #aa0000 100%) !important;
386
  transform: translateY(-3px) !important;
387
  box-shadow: 0 12px 30px rgba(255, 0, 0, 0.4) !important;
388
  }}
389
-
390
  .submit-button:active {{
391
  transform: translateY(-1px) !important;
392
  }}
393
-
394
  .accordion-container {{
395
  background: rgba(26, 26, 26, 0.8) !important;
396
  border: 1px solid #333333 !important;
397
  border-radius: 15px !important;
398
  margin-top: 2rem !important;
399
  }}
400
-
401
  .slider-container label {{
402
  color: #ffffff !important;
403
  font-weight: 600 !important;
404
  font-size: 1rem !important;
405
  }}
406
-
407
  .slider-container input[type="range"] {{
408
  accent-color: #ff0000 !important;
409
  }}
410
-
411
  .status-container textarea {{
412
  background: transparent !important;
413
  border: none !important;
@@ -415,24 +346,20 @@ custom_css = f"""
415
  font-weight: 600 !important;
416
  text-align: center !important;
417
  }}
418
-
419
  .footer {{
420
  display: none !important;
421
  }}
422
-
423
  /* Enhanced chat styling */
424
  .message.user {{
425
  background: linear-gradient(135deg, #2a2a2a 0%, #3a3a2a 100%) !important;
426
  border-left: 4px solid #ff0000 !important;
427
  margin-left: 2rem !important;
428
  }}
429
-
430
  .message.bot {{
431
  background: linear-gradient(135deg, #1a2a1a 0%, #2a3a2a 100%) !important;
432
  border-left: 4px solid #cc0000 !important;
433
  margin-right: 2rem !important;
434
  }}
435
-
436
  /* Responsive design */
437
  @media (max-width: 768px) {{
438
  .main-header h1 {{
@@ -452,7 +379,6 @@ custom_css = f"""
452
  font-size: 2rem !important;
453
  }}
454
  }}
455
-
456
  /* Animations */
457
  @keyframes pulse-glow {{
458
  0% {{
@@ -468,12 +394,10 @@ custom_css = f"""
468
  transform: scale(1);
469
  }}
470
  }}
471
-
472
  @keyframes float {{
473
  0%, 100% {{ transform: translateY(0px); }}
474
  50% {{ transform: translateY(-10px); }}
475
  }}
476
-
477
  .floating {{
478
  animation: float 3s ease-in-out infinite;
479
  }}
@@ -497,13 +421,13 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
497
  logo_html = f"""
498
  <div class="main-header">
499
  <div class="logo-container">
500
- <img src="https://huggingface.co/spaces/Yordann/MasterBrand_ChatBot/resolve/main/logo.png" alt="MasterBrand Logo" class="logo-image floating style="height:100px;">
501
  <div class="brand-text">MASTERBRAND</div>
502
  </div>
503
  <h1>AI ASSISTANT</h1>
504
- <p>Your Personal E-commerce Business Expert - Available in English & Bulgarian</p>
505
  <p style="font-size: 1rem; color: #ff0000; font-weight: 600; margin-top: 1rem;">
506
- 🚀 Powered by Advanced AI • 🌍 Multilingual Support • 💼 Expert Business Guidance
507
  </p>
508
  </div>
509
  """
@@ -526,7 +450,7 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
526
  with gr.Column(elem_classes=["input-section"]):
527
  gr.HTML('<div class="input-label"><span class="input-icon">💬</span>Ask Your Question</div>')
528
  inputs = gr.Textbox(
529
- placeholder="Ask me anything about your e-commerce business please... 💡",
530
  label="",
531
  lines=3,
532
  elem_classes=["enhanced-textbox"],
@@ -538,7 +462,7 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
538
  gr.HTML('<div class="input-label"><span class="input-icon">🖼️</span>Upload Image (Optional)</div>')
539
  image_input = gr.Image(
540
  label="",
541
- type="pil",
542
  elem_classes=["enhanced-image-input"],
543
  show_label=False
544
  )
@@ -560,7 +484,7 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
560
  )
561
 
562
  submit_btn = gr.Button(
563
- "🚀 Get Expert Advice",
564
  variant="primary",
565
  size="lg",
566
  elem_classes=["submit-button"]
@@ -586,7 +510,7 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
586
  )
587
  temperature = gr.Slider(
588
  0.1, 2.0,
589
- value=1.0,
590
  step=0.1,
591
  label="🌡️ Temperature",
592
  elem_classes=["slider-container"],
@@ -597,10 +521,10 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
597
  gr.HTML("""
598
  <div style="text-align: center; padding: 2rem; color: #666666; border-top: 1px solid #333333; margin-top: 3rem;">
599
  <p style="margin: 0; font-size: 0.9rem;">
600
- © 2025 MasterBrand AI Assistant • Built with ❤️ for E-commerce Success
601
  </p>
602
  <p style="margin: 0.5rem 0 0 0; font-size: 0.8rem; color: #888888;">
603
- Empowering entrepreneurs worldwide with AI-driven business insights
604
  </p>
605
  </div>
606
  """
@@ -629,4 +553,3 @@ with gr.Blocks(theme=masterbrand_theme, css=custom_css, title="MasterBrand Assis
629
  # ==== Launch ====
630
  if __name__ == "__main__":
631
  demo.queue(max_size=10).launch(server_name="0.0.0.0", server_port=7860)
632
-
 
1
  import gradio as gr
2
+ import openai
 
3
  from langdetect import detect
 
4
  import os
 
5
  from PIL import Image
6
  from transformers import BlipProcessor, BlipForConditionalGeneration
7
  import requests
8
  from bs4 import BeautifulSoup
9
  import cv2
 
10
  import torch
 
 
 
11
 
12
+ # Set up OpenAI API key
13
+ openai.api_key = os.getenv("OPENAI_API_KEY")
14
 
15
+ # Translation pipelines (keeping these for language support)
16
+ from transformers import pipeline
17
  bg_to_en = pipeline("translation", model="Helsinki-NLP/opus-mt-bg-en")
18
  en_to_bg = pipeline("translation", model="Helsinki-NLP/opus-mt-en-bg")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
  # Load BLIP for image captioning
21
  blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
 
23
  blip_model.to("cuda" if torch.cuda.is_available() else "cpu")
24
 
25
  def describe_image(image):
26
+ """Generate description for uploaded images"""
27
  inputs = blip_processor(images=image, return_tensors="pt").to(blip_model.device)
28
  out = blip_model.generate(**inputs)
29
  caption = blip_processor.decode(out[0], skip_special_tokens=True)
30
  return caption
31
 
32
  def describe_video(video_path):
33
+ """Extract first frame from video and describe it"""
34
  cap = cv2.VideoCapture(video_path)
35
  success, frame = cap.read()
36
  cap.release()
 
41
  return "Could not read video frame."
42
 
43
  def extract_text_from_url(url):
44
+ """Extract text content from provided URL"""
45
  try:
46
  response = requests.get(url, timeout=5)
47
  soup = BeautifulSoup(response.text, 'html.parser')
 
51
  except Exception as e:
52
  return f"Failed to fetch URL: {str(e)}"
53
 
54
+ def generate_chatgpt_response(messages, temperature=0.7):
55
+ """Generate response using OpenAI's ChatGPT API"""
56
+ try:
57
+ response = openai.ChatCompletion.create(
58
+ model="gpt-3.5-turbo", # You can change this to "gpt-4" if you have access
59
+ messages=messages,
60
+ temperature=temperature,
61
+ max_tokens=500,
62
+ top_p=1.0,
63
+ frequency_penalty=0.0,
64
+ presence_penalty=0.0
65
+ )
66
+ return response.choices[0].message.content
67
+ except Exception as e:
68
+ return f"Error generating response: {str(e)}"
69
+
70
  def generate_response(user_input, top_p, temperature, chat_counter, chatbot, history, image=None, video=None, url=None, request: gr.Request = None):
71
+ """Main function to generate AI responses"""
72
  lang = detect(user_input)
73
  print(f"Detected language: {lang}")
74
 
 
78
  else:
79
  user_input_translated = user_input
80
 
81
+ # Build the conversation context for ChatGPT
82
+ messages = [
83
+ {"role": "system", "content": "You are a helpful AI assistant. Provide clear, friendly, and informative responses to user questions."}
84
+ ]
85
+
86
+ # Add conversation history
87
+ for msg in history:
88
+ messages.append(msg)
89
 
90
+ # Prepare the current user message
91
+ current_message = user_input_translated
92
 
93
  # Multimodal additions
94
  if image is not None:
95
  try:
96
  img_desc = describe_image(image)
97
+ current_message += f"\n[Image Description]: {img_desc}"
98
  except Exception as e:
99
+ current_message += f"\n[Image Error]: {str(e)}"
100
 
101
  if video is not None:
102
  try:
103
  vid_desc = describe_video(video)
104
+ current_message += f"\n[Video Description]: {vid_desc}"
105
  except Exception as e:
106
+ current_message += f"\n[Video Error]: {str(e)}"
107
 
108
  if url:
109
  url_content = extract_text_from_url(url)
110
+ current_message += f"\n[URL Content]: {url_content}"
111
 
112
+ # Add current user message
113
+ messages.append({"role": "user", "content": current_message})
114
 
115
+ # Generate response using ChatGPT
116
+ response_text = generate_chatgpt_response(messages, temperature)
117
 
118
+ # Translate back if needed
119
  if lang == "bg":
120
  response_text = en_to_bg(response_text)[0]["translation_text"]
121
 
 
127
  return history, history, chat_counter, "✅ Success", gr.update(value=''), gr.update(interactive=True)
128
 
129
  def reset_textbox():
130
+ """Reset the input textbox"""
131
  return gr.update(value='')
132
 
133
  # ==== Enhanced Custom CSS with Masterbrand Styling ====
134
  custom_css = f"""
135
  @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap');
 
136
  * {{
137
  font-family: 'Inter', sans-serif !important;
138
  }}
 
139
  .gradio-container {{
140
  background: linear-gradient(135deg, #0a0a0a 0%, #1a0a0a 50%, #2a1a1a 100%) !important;
141
  min-height: 100vh !important;
142
  }}
 
143
  .main-header {{
144
  background: linear-gradient(135deg, #0a0a0a 0%, #1a0a0a 50%, #2a1a1a 100%) !important;
145
  padding: 2rem 0 3rem 0 !important;
 
149
  position: relative !important;
150
  overflow: hidden !important;
151
  }}
 
152
  .main-header::before {{
153
  content: '';
154
  position: absolute;
 
159
  background: radial-gradient(circle at 50% 50%, rgba(255, 0, 0, 0.1) 0%, transparent 70%);
160
  pointer-events: none;
161
  }}
 
162
  .logo-container {{
163
  display: flex !important;
164
  justify-content: center !important;
 
166
  margin-bottom: 1.5rem !important;
167
  gap: 1rem !important;
168
  }}
 
169
  .logo-image {{
170
  width: 50px !important;
171
  height: 50px !important;
 
174
  animation: pulse-glow 2s ease-in-out infinite alternate !important;
175
  transition: transform 0.3s ease !important;
176
  }}
 
177
  .logo-image:hover {{
178
  transform: scale(1.1) !important;
179
  }}
 
180
  .brand-text {{
181
  background: linear-gradient(135deg, #00ff41 0%, #ffffff 50%, #ff0000 100%) !important;
182
  -webkit-background-clip: text !important;
 
187
  letter-spacing: 2px !important;
188
  text-shadow: 0 0 20px rgba(0, 255, 65, 0.3) !important;
189
  }}
 
190
  .main-header h1 {{
191
  color: #ffffff !important;
192
  font-size: 3.5rem !important;
 
198
  background-clip: text !important;
199
  margin: 0 !important;
200
  }}
 
201
  .main-header p {{
202
  color: #cccccc !important;
203
  font-size: 1.3rem !important;
204
  font-weight: 500 !important;
205
  margin-top: 0.5rem !important;
206
  }}
 
207
  .chatbot-container {{
208
  background: rgba(26, 26, 26, 0.95) !important;
209
  border: 2px solid #ff0000 !important;
 
212
  margin-bottom: 2rem !important;
213
  backdrop-filter: blur(10px) !important;
214
  }}
 
215
  .input-section {{
216
  background: rgba(26, 26, 26, 0.8) !important;
217
  border: 2px solid #333333 !important;
 
222
  backdrop-filter: blur(10px) !important;
223
  transition: all 0.3s ease !important;
224
  }}
 
225
  .input-section:hover {{
226
  border-color: #ff0000 !important;
227
  box-shadow: 0 15px 40px rgba(255, 0, 0, 0.2) !important;
228
  }}
 
229
  .input-group {{
230
  margin-bottom: 1.5rem !important;
231
  }}
 
232
  .input-group:last-child {{
233
  margin-bottom: 0 !important;
234
  }}
 
235
  .input-label {{
236
  color: #ffffff !important;
237
  font-size: 1.1rem !important;
 
241
  align-items: center !important;
242
  gap: 0.5rem !important;
243
  }}
 
244
  .input-icon {{
245
  font-size: 1.2rem !important;
246
  color: #ff0000 !important;
247
  }}
 
248
  .enhanced-textbox textarea {{
249
  background: linear-gradient(135deg, #1a1a1a 0%, #2a2a1a 100%) !important;
250
  border: 2px solid #444444 !important;
 
256
  transition: all 0.3s ease !important;
257
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3) !important;
258
  }}
 
259
  .enhanced-textbox textarea:focus {{
260
  border-color: #ff0000 !important;
261
  box-shadow: 0 0 25px rgba(255, 0, 0, 0.4), 0 5px 15px rgba(0, 0, 0, 0.3) !important;
262
  outline: none !important;
263
  transform: translateY(-2px) !important;
264
  }}
 
265
  .enhanced-textbox textarea::placeholder {{
266
  color: #888888 !important;
267
  font-style: italic !important;
268
  }}
 
269
  .enhanced-image-input, .enhanced-video-input {{
270
  background: rgba(42, 42, 42, 0.8) !important;
271
  border: 2px dashed #444444 !important;
 
278
  align-items: center !important;
279
  justify-content: center !important;
280
  }}
 
281
  .enhanced-image-input:hover, .enhanced-video-input:hover {{
282
  border-color: #ff0000 !important;
283
  background: rgba(255, 0, 0, 0.05) !important;
284
  }}
 
285
  .enhanced-url-input input {{
286
  background: linear-gradient(135deg, #1a1a1a 0%, #2a2a1a 100%) !important;
287
  border: 2px solid #444444 !important;
 
292
  transition: all 0.3s ease !important;
293
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3) !important;
294
  }}
 
295
  .enhanced-url-input input:focus {{
296
  border-color: #ff0000 !important;
297
  box-shadow: 0 0 25px rgba(255, 0, 0, 0.4), 0 5px 15px rgba(0, 0, 0, 0.3) !important;
298
  outline: none !important;
299
  transform: translateY(-2px) !important;
300
  }}
 
301
  .enhanced-url-input input::placeholder {{
302
  color: #888888 !important;
303
  font-style: italic !important;
304
  }}
 
305
  .submit-button {{
306
  background: linear-gradient(135deg, #ff0000 0%, #cc0000 100%) !important;
307
  border: none !important;
 
317
  width: 100% !important;
318
  margin-top: 1rem !important;
319
  }}
 
320
  .submit-button:hover {{
321
  background: linear-gradient(135deg, #cc0000 0%, #aa0000 100%) !important;
322
  transform: translateY(-3px) !important;
323
  box-shadow: 0 12px 30px rgba(255, 0, 0, 0.4) !important;
324
  }}
 
325
  .submit-button:active {{
326
  transform: translateY(-1px) !important;
327
  }}
 
328
  .accordion-container {{
329
  background: rgba(26, 26, 26, 0.8) !important;
330
  border: 1px solid #333333 !important;
331
  border-radius: 15px !important;
332
  margin-top: 2rem !important;
333
  }}
 
334
  .slider-container label {{
335
  color: #ffffff !important;
336
  font-weight: 600 !important;
337
  font-size: 1rem !important;
338
  }}
 
339
  .slider-container input[type="range"] {{
340
  accent-color: #ff0000 !important;
341
  }}
 
342
  .status-container textarea {{
343
  background: transparent !important;
344
  border: none !important;
 
346
  font-weight: 600 !important;
347
  text-align: center !important;
348
  }}
 
349
  .footer {{
350
  display: none !important;
351
  }}
 
352
  /* Enhanced chat styling */
353
  .message.user {{
354
  background: linear-gradient(135deg, #2a2a2a 0%, #3a3a2a 100%) !important;
355
  border-left: 4px solid #ff0000 !important;
356
  margin-left: 2rem !important;
357
  }}
 
358
  .message.bot {{
359
  background: linear-gradient(135deg, #1a2a1a 0%, #2a3a2a 100%) !important;
360
  border-left: 4px solid #cc0000 !important;
361
  margin-right: 2rem !important;
362
  }}
 
363
  /* Responsive design */
364
  @media (max-width: 768px) {{
365
  .main-header h1 {{
 
379
  font-size: 2rem !important;
380
  }}
381
  }}
 
382
  /* Animations */
383
  @keyframes pulse-glow {{
384
  0% {{
 
394
  transform: scale(1);
395
  }}
396
  }}
 
397
  @keyframes float {{
398
  0%, 100% {{ transform: translateY(0px); }}
399
  50% {{ transform: translateY(-10px); }}
400
  }}
 
401
  .floating {{
402
  animation: float 3s ease-in-out infinite;
403
  }}
 
421
  logo_html = f"""
422
  <div class="main-header">
423
  <div class="logo-container">
424
+ <img src="https://huggingface.co/spaces/Yordann/MasterBrand_ChatBot/resolve/main/logo.png" alt="MasterBrand Logo" class="logo-image floating" style="height:100px;">
425
  <div class="brand-text">MASTERBRAND</div>
426
  </div>
427
  <h1>AI ASSISTANT</h1>
428
+ <p>Your Personal AI Assistant - Powered by ChatGPT - Available in English & Bulgarian</p>
429
  <p style="font-size: 1rem; color: #ff0000; font-weight: 600; margin-top: 1rem;">
430
+ 🚀 Powered by ChatGPT • 🌍 Multilingual Support • 💼 General AI Assistance
431
  </p>
432
  </div>
433
  """
 
450
  with gr.Column(elem_classes=["input-section"]):
451
  gr.HTML('<div class="input-label"><span class="input-icon">💬</span>Ask Your Question</div>')
452
  inputs = gr.Textbox(
453
+ placeholder="Ask me anything... 💡",
454
  label="",
455
  lines=3,
456
  elem_classes=["enhanced-textbox"],
 
462
  gr.HTML('<div class="input-label"><span class="input-icon">🖼️</span>Upload Image (Optional)</div>')
463
  image_input = gr.Image(
464
  label="",
465
+ type="pil",
466
  elem_classes=["enhanced-image-input"],
467
  show_label=False
468
  )
 
484
  )
485
 
486
  submit_btn = gr.Button(
487
+ "🚀 Get AI Response",
488
  variant="primary",
489
  size="lg",
490
  elem_classes=["submit-button"]
 
510
  )
511
  temperature = gr.Slider(
512
  0.1, 2.0,
513
+ value=0.7,
514
  step=0.1,
515
  label="🌡️ Temperature",
516
  elem_classes=["slider-container"],
 
521
  gr.HTML("""
522
  <div style="text-align: center; padding: 2rem; color: #666666; border-top: 1px solid #333333; margin-top: 3rem;">
523
  <p style="margin: 0; font-size: 0.9rem;">
524
+ © 2025 MasterBrand AI Assistant • Powered by ChatGPT
525
  </p>
526
  <p style="margin: 0.5rem 0 0 0; font-size: 0.8rem; color: #888888;">
527
+ Your intelligent AI companion for any task
528
  </p>
529
  </div>
530
  """
 
553
  # ==== Launch ====
554
  if __name__ == "__main__":
555
  demo.queue(max_size=10).launch(server_name="0.0.0.0", server_port=7860)