Waseem771 commited on
Commit
a95c8d9
Β·
verified Β·
1 Parent(s): b11f94e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +322 -106
app.py CHANGED
@@ -1,8 +1,10 @@
1
  import streamlit as st
2
- from transformers import AutoTokenizer, AutoModelForCausalLM
3
- import torch
4
  import requests
5
  import os
 
 
 
 
6
 
7
  # Page configuration
8
  st.set_page_config(
@@ -11,29 +13,63 @@ st.set_page_config(
11
  layout="centered"
12
  )
13
 
14
- # Check for API usage vs local model
15
- use_api = st.sidebar.checkbox("Use Hugging Face API (recommended)", value=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
- if use_api:
18
- # Hugging Face API setup
19
- API_URL = "https://api-inference.huggingface.co/models/meta-llama/Llama-2-7b-chat-hf"
20
- API_TOKEN = os.environ.get("HF_API_TOKEN", st.secrets.get("HF_API_TOKEN", ""))
21
- headers = {"Authorization": f"Bearer {API_TOKEN}"}
22
-
23
- # Show warning if no API token is provided
24
- if not API_TOKEN:
25
- st.sidebar.warning("⚠️ No API token found. Please add one in your secrets.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  else:
27
- # Load model and tokenizer locally (fallback option)
28
- @st.cache_resource
29
- def load_model():
30
- model_name = "facebook/blenderbot-400M-distill"
31
- tokenizer = AutoTokenizer.from_pretrained(model_name)
32
- model = AutoModelForCausalLM.from_pretrained(model_name)
33
- return tokenizer, model
34
-
35
- with st.spinner("Loading model... This might take a minute."):
36
- tokenizer, model = load_model()
37
 
38
  # Customer support context and guidelines
39
  SYSTEM_PROMPT = """You are an AI-powered customer support assistant integrated into a company website.
@@ -46,6 +82,7 @@ Rules:
46
  - Direct users to relevant resources when needed
47
  - Be available 24/7 and never mention that you're an AI unless explicitly asked
48
  - Avoid hallucinating facts - if you don't know something, politely let the user know and offer to connect them with a human representative
 
49
 
50
  Example questions you should be able to handle:
51
  - "I need help tracking my order"
@@ -65,86 +102,205 @@ COMPANY_INFO = {
65
  "contact": "For complex issues, you can reach our human support team at support@example.com or call 1-800-123-4567."
66
  }
67
 
68
- def format_user_prompt(user_input, history):
69
- """Format the input with history for local model"""
70
- prompt = SYSTEM_PROMPT + "\n\n"
71
- for user_msg, bot_msg in history:
72
- prompt += f"Customer: {user_msg}\nSupport: {bot_msg}\n\n"
73
- prompt += f"Customer: {user_input}\nSupport:"
74
- return prompt
 
 
 
 
75
 
76
- def format_prompt_for_llama2(user_input, history):
77
- """Format the prompt for Llama-2 chat model"""
78
- messages = [{"role": "system", "content": SYSTEM_PROMPT}]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- # Add chat history
81
- for user_msg, bot_msg in history:
82
- messages.append({"role": "user", "content": user_msg})
83
- messages.append({"role": "assistant", "content": bot_msg})
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
- # Add current user message
86
- messages.append({"role": "user", "content": user_input})
87
 
88
- return messages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
- def query_huggingface_api(payload):
91
- """Send request to Hugging Face API"""
92
  try:
93
- response = requests.post(API_URL, headers=headers, json=payload)
94
- return response.json()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  except Exception as e:
96
- st.error(f"Error querying API: {e}")
97
- return {"error": str(e)}
98
-
99
- def get_local_model_response(user_input, history):
100
- """Generate response using the local model"""
101
- prompt = format_user_prompt(user_input, history)
102
-
103
- # Generate response
104
- inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512)
105
- with torch.no_grad():
106
- output = model.generate(
107
- inputs["input_ids"],
108
- max_length=200,
109
- num_return_sequences=1,
110
- temperature=0.7,
111
- top_p=0.9,
112
- do_sample=True,
113
- pad_token_id=tokenizer.eos_token_id
114
- )
115
-
116
- response = tokenizer.decode(output[0], skip_special_tokens=True)
117
-
118
- # Extract just the assistant's response (after Support:)
119
- try:
120
- response = response.split("Support:")[-1].strip()
121
- except:
122
- response = "I apologize, but I'm having trouble generating a response. Please try rephrasing your question, or I'd be happy to connect you with a human representative."
123
 
124
- return response
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
 
126
- def get_api_response(user_input, history):
127
- """Get response from the LLM via Hugging Face API"""
128
- # Format the messages for the API
129
- messages = format_prompt_for_llama2(user_input, history)
 
 
 
 
130
 
131
  # Query the API
132
- response = query_huggingface_api({"inputs": messages})
 
 
 
 
133
 
134
  # Extract the assistant's response
135
- try:
136
- if isinstance(response, list) and len(response) > 0:
137
- assistant_response = response[0].get("generated_text", "")
138
- elif isinstance(response, dict) and "generated_text" in response:
139
- assistant_response = response["generated_text"]
140
- else:
141
- st.warning(f"Unexpected API response format")
142
- assistant_response = "I apologize, but I'm having trouble generating a response. Please try rephrasing your question, or I'd be happy to connect you with a human representative."
143
- except Exception as e:
144
- st.error(f"Error processing API response: {e}")
145
- assistant_response = "I apologize, but I'm having trouble generating a response. Please try rephrasing your question, or I'd be happy to connect you with a human representative."
146
 
147
- return assistant_response
 
148
 
149
  def enhance_response(user_input, base_response):
150
  """Enhance response with specific company information"""
@@ -165,23 +321,19 @@ def enhance_response(user_input, base_response):
165
 
166
  return base_response
167
 
168
- def get_response(user_input, history):
169
- """Get chatbot response based on the selected mode"""
170
- if use_api:
171
- base_response = get_api_response(user_input, history)
172
- else:
173
- base_response = get_local_model_response(user_input, history)
174
-
175
- # Enhance with specific company information
176
- return enhance_response(user_input, base_response)
177
-
178
  # App title and intro
179
  st.title("Customer Support Assistant")
180
  st.markdown("Welcome to our customer support chat! How can I help you today?")
181
 
182
- # Initialize session state for chat history
183
  if "chat_history" not in st.session_state:
184
  st.session_state.chat_history = []
 
 
 
 
 
 
185
 
186
  # Display chat history
187
  for user_msg, bot_msg in st.session_state.chat_history:
@@ -200,21 +352,85 @@ if user_input:
200
 
201
  # Get bot response with a spinner
202
  with st.chat_message("assistant", avatar="πŸ§‘β€πŸ’Ό"):
203
- with st.spinner("Thinking..."):
204
- bot_response = get_response(user_input, st.session_state.chat_history)
205
- st.write(bot_response)
206
-
207
- # Add to chat history
208
- st.session_state.chat_history.append((user_input, bot_response))
 
 
 
209
 
210
  # Sidebar options
211
  with st.sidebar:
212
  st.title("Options")
213
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  if st.button("Clear Conversation"):
215
  st.session_state.chat_history = []
216
  st.experimental_rerun()
217
 
 
 
 
 
 
 
 
 
 
218
  st.markdown("---")
219
  st.markdown("### About")
220
  st.markdown("This customer support chatbot is powered by AI and provides assistance for common customer inquiries.")
 
1
  import streamlit as st
 
 
2
  import requests
3
  import os
4
+ import toml
5
+ import pathlib
6
+ import json
7
+ import time
8
 
9
  # Page configuration
10
  st.set_page_config(
 
13
  layout="centered"
14
  )
15
 
16
+ # Try to load secrets from .streamlit/secrets.toml
17
+ def load_secrets():
18
+ try:
19
+ # First, try streamlit's built-in secrets
20
+ if hasattr(st, 'secrets'):
21
+ try:
22
+ return st.secrets.get("HF_API_TOKEN", "")
23
+ except:
24
+ pass
25
+
26
+ # Second, try to find secrets.toml in the .streamlit directory
27
+ secrets_path = pathlib.Path(".streamlit/secrets.toml")
28
+ if secrets_path.exists():
29
+ secrets = toml.load(secrets_path)
30
+ return secrets.get("HF_API_TOKEN", "")
31
+
32
+ # Third, check in user's home directory
33
+ home_secrets_path = pathlib.Path.home() / ".streamlit/secrets.toml"
34
+ if home_secrets_path.exists():
35
+ secrets = toml.load(home_secrets_path)
36
+ return secrets.get("HF_API_TOKEN", "")
37
+
38
+ # Last, check environment variables
39
+ return os.environ.get("HF_API_TOKEN", "")
40
+ except Exception as e:
41
+ st.sidebar.error(f"Error loading secrets: {e}")
42
+ return ""
43
 
44
+ # Model selection
45
+ MODEL_OPTIONS = {
46
+ "Llama-3-8B-Instruct": "meta-llama/Meta-Llama-3-8B-Instruct", # More up-to-date model
47
+ "Llama-2-7B-Chat": "meta-llama/Llama-2-7b-chat-hf",
48
+ "Mistral-7B-Instruct": "mistralai/Mistral-7B-Instruct-v0.2",
49
+ "Falcon-7B-Instruct": "tiiuae/falcon-7b-instruct",
50
+ "OpenAssistant": "OpenAssistant/oasst-sft-4-pythia-12b-epoch-3.5",
51
+ "Flan-T5-Large": "google/flan-t5-large", # Open access model
52
+ "GPT2": "gpt2", # Fully open model
53
+ "Rule-Based (No API)": "local" # Completely local option
54
+ }
55
+
56
+ # Allow model selection and initialize with default
57
+ if "selected_model" not in st.session_state:
58
+ st.session_state.selected_model = "Rule-Based (No API)" # Default to local option for reliability
59
+
60
+ # Hugging Face API setup
61
+ def get_api_url():
62
+ model_id = MODEL_OPTIONS[st.session_state.selected_model]
63
+ return f"https://api-inference.huggingface.co/models/{model_id}"
64
+
65
+ API_TOKEN = load_secrets()
66
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
67
+
68
+ # Show warning if no API token is provided
69
+ if not API_TOKEN:
70
+ st.sidebar.warning("⚠️ No API token found. Using fallback responses. Add your API token in environment variables or create a .streamlit/secrets.toml file.")
71
  else:
72
+ st.sidebar.success("βœ… API token loaded successfully")
 
 
 
 
 
 
 
 
 
73
 
74
  # Customer support context and guidelines
75
  SYSTEM_PROMPT = """You are an AI-powered customer support assistant integrated into a company website.
 
82
  - Direct users to relevant resources when needed
83
  - Be available 24/7 and never mention that you're an AI unless explicitly asked
84
  - Avoid hallucinating facts - if you don't know something, politely let the user know and offer to connect them with a human representative
85
+ - Keep responses concise and to the point
86
 
87
  Example questions you should be able to handle:
88
  - "I need help tracking my order"
 
102
  "contact": "For complex issues, you can reach our human support team at support@example.com or call 1-800-123-4567."
103
  }
104
 
105
+ # Fallback responses for common queries when API is not available
106
+ FALLBACK_RESPONSES = {
107
+ "greeting": "Hello! Welcome to our customer support. How can I assist you today?",
108
+ "return": f"Our return policy allows returns within 30 days of purchase with original receipt. Items must be unused and in original packaging.",
109
+ "track": "You can track your order by logging into your account or using the tracking number provided in your confirmation email.",
110
+ "login": "For account login issues, try resetting your password. If problems persist, please provide your email address so we can investigate.",
111
+ "subscription": "Yes, you can cancel your subscription at any time through your account settings. There are no cancellation fees.",
112
+ "hours": "Our customer support team is available 24/7 via this chat. For phone support, our hours are 9 AM - 8 PM Monday through Friday, and 10 AM - 6 PM on weekends.",
113
+ "contact": "For complex issues, you can reach our human support team at support@example.com or call 1-800-123-4567.",
114
+ "default": "Thank you for your inquiry. I'd be happy to help with that. Could you please provide more details so I can assist you better?"
115
+ }
116
 
117
+ def format_prompt(user_input, history):
118
+ """Format the prompt for the selected model"""
119
+ if st.session_state.selected_model in ["Llama-3-8B-Instruct", "Llama-2-7B-Chat"]:
120
+ messages = [{"role": "system", "content": SYSTEM_PROMPT}]
121
+
122
+ # Add chat history
123
+ for user_msg, bot_msg in history:
124
+ messages.append({"role": "user", "content": user_msg})
125
+ messages.append({"role": "assistant", "content": bot_msg})
126
+
127
+ # Add current user message
128
+ messages.append({"role": "user", "content": user_input})
129
+
130
+ return {"inputs": messages}
131
+ elif st.session_state.selected_model == "Flan-T5-Large":
132
+ # Special format for Flan-T5
133
+ # Flan-T5 works better with direct questions/instructions
134
+ prompt = f"Answer this customer support question in a helpful way: {user_input}"
135
+ return {"inputs": prompt}
136
+ elif st.session_state.selected_model == "GPT2":
137
+ # Special format for GPT2
138
+ prompt = f"Customer: {user_input}\nSupport agent:"
139
+ return {"inputs": prompt}
140
+ else:
141
+ # For other models that use text completion format
142
+ prompt = SYSTEM_PROMPT + "\n\n"
143
+ for user_msg, bot_msg in history:
144
+ prompt += f"User: {user_msg}\nAssistant: {bot_msg}\n\n"
145
+ prompt += f"User: {user_input}\nAssistant:"
146
+
147
+ return {"inputs": prompt}
148
+
149
+ def query_huggingface_api(payload, user_input):
150
+ """Send request to Hugging Face API with retry logic"""
151
+ api_url = get_api_url()
152
+ max_retries = 3
153
+ retry_delay = 2
154
 
155
+ # Try alternative TGI API endpoint if selected
156
+ use_tgi_api = False
157
+ if "use_tgi_api" in st.session_state and st.session_state.use_tgi_api:
158
+ use_tgi_api = True
159
+ # The TGI API has a different format
160
+ if st.session_state.selected_model in ["Llama-3-8B-Instruct", "Llama-2-7B-Chat", "Mistral-7B-Instruct"]:
161
+ # Extract just the messages for chat models
162
+ if "inputs" in payload and isinstance(payload["inputs"], list):
163
+ tgi_payload = {
164
+ "inputs": payload["inputs"][-1]["content"],
165
+ "parameters": {
166
+ "max_new_tokens": 256,
167
+ "temperature": 0.7,
168
+ "top_p": 0.95,
169
+ "do_sample": True
170
+ }
171
+ }
172
+ payload = tgi_payload
173
+ api_url = f"https://api-inference.huggingface.co/models/{MODEL_OPTIONS[st.session_state.selected_model]}"
174
 
175
+ original_payload = payload.copy()
176
+ tried_simple_string = False
177
 
178
+ for attempt in range(max_retries):
179
+ try:
180
+ response = requests.post(api_url, headers=headers, json=payload, timeout=90)
181
+
182
+ # Check if model is still loading
183
+ if response.status_code == 503:
184
+ st.warning(f"Model is loading. Retrying in {retry_delay} seconds... (Attempt {attempt+1}/{max_retries})")
185
+ time.sleep(retry_delay)
186
+ retry_delay *= 2 # Exponential backoff
187
+ continue
188
+
189
+ # Handle 422 errors specifically - try simplifying the input format
190
+ if response.status_code == 422 and not tried_simple_string:
191
+ st.warning("Model expecting different input format. Trying simpler format...")
192
+ # Convert to simple string input
193
+ if isinstance(payload["inputs"], dict) or isinstance(payload["inputs"], list):
194
+ # Extract just the user's query for simplicity
195
+ payload = {"inputs": user_input}
196
+ tried_simple_string = True
197
+ continue
198
+
199
+ # Handle other errors
200
+ if response.status_code != 200:
201
+ st.error(f"API error: {response.status_code} - {response.text}")
202
+ return {"error": f"API error: {response.status_code} - {response.text}"}
203
+
204
+ return response.json()
205
+
206
+ except Exception as e:
207
+ st.error(f"Error querying API (attempt {attempt+1}/{max_retries}): {e}")
208
+ if attempt < max_retries - 1:
209
+ time.sleep(retry_delay)
210
+ retry_delay *= 2
211
+ else:
212
+ return {"error": str(e)}
213
 
214
+ def extract_response(api_response):
215
+ """Extract the response text from different model response formats"""
216
  try:
217
+ if "debug_mode" in st.session_state and st.session_state.debug_mode:
218
+ st.sidebar.subheader("Raw Response:")
219
+ st.sidebar.json(api_response)
220
+
221
+ # Handle list format responses
222
+ if isinstance(api_response, list):
223
+ if len(api_response) > 0:
224
+ # Standard response format for some models
225
+ if "generated_text" in api_response[0]:
226
+ return api_response[0]["generated_text"]
227
+ # TGI API direct text response
228
+ elif isinstance(api_response[0], str):
229
+ return api_response[0]
230
+
231
+ # Handle dictionary format responses
232
+ if isinstance(api_response, dict):
233
+ # For text generation models
234
+ if "generated_text" in api_response:
235
+ return api_response["generated_text"]
236
+
237
+ # For simple string response in a dict
238
+ if "text" in api_response:
239
+ return api_response["text"]
240
+
241
+ # For chat models that return as list array
242
+ if "conversation" in api_response:
243
+ return api_response["conversation"]["messages"][-1]["content"]
244
+
245
+ # For Llama-3/Mistral chat format
246
+ if "outputs" in api_response and len(api_response["outputs"]) > 0:
247
+ return api_response["outputs"][0]["text"]
248
+
249
+ # Fallback: attempt to extract any text or return the response as string
250
+ if isinstance(api_response, str):
251
+ return api_response
252
+
253
+ return str(api_response)
254
+
255
  except Exception as e:
256
+ st.error(f"Error extracting response: {e}")
257
+ return None
258
+
259
+ def get_fallback_response(user_input):
260
+ """Get a fallback response based on keywords in the user input"""
261
+ lower_input = user_input.lower()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
262
 
263
+ if any(word in lower_input for word in ["hi", "hello", "hey"]):
264
+ return FALLBACK_RESPONSES["greeting"]
265
+ elif "return" in lower_input:
266
+ return FALLBACK_RESPONSES["return"]
267
+ elif any(word in lower_input for word in ["track", "order", "package", "shipping"]):
268
+ return FALLBACK_RESPONSES["track"]
269
+ elif any(word in lower_input for word in ["login", "sign in", "account", "password"]):
270
+ return FALLBACK_RESPONSES["login"]
271
+ elif "subscription" in lower_input:
272
+ return FALLBACK_RESPONSES["subscription"]
273
+ elif any(word in lower_input for word in ["hours", "available", "weekend"]):
274
+ return FALLBACK_RESPONSES["hours"]
275
+ elif any(word in lower_input for word in ["human", "person", "agent", "representative"]):
276
+ return FALLBACK_RESPONSES["contact"]
277
+ else:
278
+ return FALLBACK_RESPONSES["default"]
279
 
280
+ def get_response(user_input, history):
281
+ """Get response from the LLM via Hugging Face API or fall back to simple responses"""
282
+ # Use rule-based responses if selected or if API token is missing
283
+ if st.session_state.selected_model == "Rule-Based (No API)" or not API_TOKEN:
284
+ return get_fallback_response(user_input)
285
+
286
+ # Format the messages for the API based on selected model
287
+ payload = format_prompt(user_input, history)
288
 
289
  # Query the API
290
+ api_response = query_huggingface_api(payload, user_input)
291
+
292
+ # Debug mode: show raw API response
293
+ if "debug_mode" in st.session_state and st.session_state.debug_mode:
294
+ st.sidebar.json(api_response)
295
 
296
  # Extract the assistant's response
297
+ if api_response and "error" not in api_response:
298
+ assistant_response = extract_response(api_response)
299
+ if assistant_response:
300
+ return assistant_response
 
 
 
 
 
 
 
301
 
302
+ # Fall back to keyword-based responses if API fails
303
+ return get_fallback_response(user_input)
304
 
305
  def enhance_response(user_input, base_response):
306
  """Enhance response with specific company information"""
 
321
 
322
  return base_response
323
 
 
 
 
 
 
 
 
 
 
 
324
  # App title and intro
325
  st.title("Customer Support Assistant")
326
  st.markdown("Welcome to our customer support chat! How can I help you today?")
327
 
328
+ # Initialize session state for chat history and API token
329
  if "chat_history" not in st.session_state:
330
  st.session_state.chat_history = []
331
+
332
+ if "api_token" not in st.session_state:
333
+ st.session_state.api_token = API_TOKEN
334
+
335
+ if "debug_mode" not in st.session_state:
336
+ st.session_state.debug_mode = False
337
 
338
  # Display chat history
339
  for user_msg, bot_msg in st.session_state.chat_history:
 
352
 
353
  # Get bot response with a spinner
354
  with st.chat_message("assistant", avatar="πŸ§‘β€πŸ’Ό"):
355
+ with st.spinner(f"Thinking using {st.session_state.selected_model}..."):
356
+ try:
357
+ base_response = get_response(user_input, st.session_state.chat_history)
358
+ bot_response = enhance_response(user_input, base_response)
359
+ st.write(bot_response)
360
+ # Add to chat history
361
+ st.session_state.chat_history.append((user_input, bot_response))
362
+ except Exception as e:
363
+ st.error(f"Sorry, I encountered an error processing your request: {str(e)}")
364
 
365
  # Sidebar options
366
  with st.sidebar:
367
  st.title("Options")
368
 
369
+ # Model selection
370
+ st.markdown("---")
371
+ st.markdown("### Model Settings")
372
+ selected_model = st.selectbox(
373
+ "Select AI Model",
374
+ list(MODEL_OPTIONS.keys()),
375
+ index=list(MODEL_OPTIONS.keys()).index(st.session_state.selected_model)
376
+ )
377
+
378
+ if selected_model != st.session_state.selected_model:
379
+ st.session_state.selected_model = selected_model
380
+ st.success(f"Model changed to {selected_model}")
381
+
382
+ # API mode toggle
383
+ st.checkbox("Use TGI API (try if regular API fails)", key="use_tgi_api",
384
+ help="Use Text Generation Inference API format which works better for some models")
385
+
386
+ # API token input
387
+ st.markdown("---")
388
+ st.markdown("### API Settings")
389
+ manually_entered_token = st.text_input("Enter Hugging Face API Token", type="password", help="Your API token will not be stored permanently")
390
+ if manually_entered_token:
391
+ st.session_state.api_token = manually_entered_token
392
+ API_TOKEN = manually_entered_token
393
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
394
+ st.success("βœ… API Token set for this session")
395
+
396
+ # Test API button
397
+ if st.button("Test API Connection"):
398
+ with st.spinner("Testing API connection..."):
399
+ test_model = "gpt2" # Use a simple model that everyone has access to
400
+ test_url = f"https://api-inference.huggingface.co/models/{test_model}"
401
+ test_payload = {"inputs": "Hello, I'm testing the API connection."}
402
+ try:
403
+ response = requests.post(test_url, headers=headers, json=test_payload, timeout=10)
404
+ if response.status_code == 200:
405
+ st.success("βœ… API connection successful! Your token is working correctly.")
406
+ # Update the API token in session
407
+ if not API_TOKEN:
408
+ st.session_state.api_token = manually_entered_token
409
+ API_TOKEN = manually_entered_token
410
+ headers = {"Authorization": f"Bearer {API_TOKEN}"}
411
+ else:
412
+ st.error(f"❌ API Error: {response.status_code} - {response.text}")
413
+ st.info("Please check your API token and try again. Make sure you're using a valid Hugging Face API token.")
414
+ except Exception as e:
415
+ st.error(f"❌ Connection Error: {str(e)}")
416
+ st.info("Please check your internet connection and try again.")
417
+
418
+ # Debug toggle
419
+ st.checkbox("Debug Mode", key="debug_mode", help="Show raw API responses in the sidebar")
420
+
421
  if st.button("Clear Conversation"):
422
  st.session_state.chat_history = []
423
  st.experimental_rerun()
424
 
425
+ # API status indicator
426
+ st.markdown("---")
427
+ if API_TOKEN:
428
+ st.success("βœ… API Connected")
429
+ st.info(f"Using model: {st.session_state.selected_model}")
430
+ else:
431
+ st.error("❌ API Not Connected")
432
+ st.info("Add your Hugging Face API token in the field above, in environment variables, or create a .streamlit/secrets.toml file")
433
+
434
  st.markdown("---")
435
  st.markdown("### About")
436
  st.markdown("This customer support chatbot is powered by AI and provides assistance for common customer inquiries.")