admin08077 commited on
Commit
2666125
·
verified ·
1 Parent(s): ff6f1c1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +303 -200
app.py CHANGED
@@ -8,12 +8,33 @@ from sklearn.feature_extraction.text import CountVectorizer
8
  from sklearn.ensemble import RandomForestClassifier
9
  from sklearn.pipeline import Pipeline
10
  import joblib
11
-
12
- # Initialize the HuggingFace API Client with a valid model
13
- # Replace 'gpt-3.5-turbo' with your desired model if different
14
- client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
15
-
16
- # Persistent memory and knowledge base setup
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  memory_file = "chat_memory.json"
18
  knowledge_base_dir = "knowledge_base"
19
  model_file = "chat_model.pkl"
@@ -21,90 +42,140 @@ model_file = "chat_model.pkl"
21
  # Ensure directories exist
22
  os.makedirs(knowledge_base_dir, exist_ok=True)
23
 
24
- # Load memory from file
 
 
25
  def load_memory():
26
- if os.path.exists(memory_file):
27
- with open(memory_file, "r") as f:
28
- return json.load(f)
29
- return []
 
 
 
 
 
 
 
 
30
 
31
- # Save memory to file
32
  def save_memory(memory):
33
- with open(memory_file, "w") as f:
34
- json.dump(memory, f, indent=2)
 
 
 
 
 
35
 
36
- # Append to memory
37
  def update_memory(message, response):
38
- memory = load_memory()
39
- memory.append({"role": "user", "content": message})
40
- memory.append({"role": "assistant", "content": response})
41
- # Optionally limit memory size
42
- if len(memory) > 1000:
43
- memory = memory[-1000:]
44
- save_memory(memory)
45
-
46
- # Load or initialize the ML model
 
 
 
 
 
 
47
  def load_or_initialize_model():
48
- if os.path.exists(model_file):
49
- return joblib.load(model_file)
50
- return Pipeline([
51
- ("vectorizer", CountVectorizer()),
52
- ("classifier", RandomForestClassifier(n_estimators=100, random_state=42))
53
- ])
54
-
55
- # Retrain model on files in the knowledge base
56
- def train_model_on_files():
57
- model = load_or_initialize_model()
58
- texts, labels = [], []
 
 
 
 
59
 
60
- # Load data from the knowledge base
61
- for file_name in os.listdir(knowledge_base_dir):
62
- file_path = os.path.join(knowledge_base_dir, file_name)
63
- if file_path.endswith(".csv"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  try:
65
- df = pd.read_csv(file_path)
66
- if "text" in df.columns and "label" in df.columns:
67
- texts.extend(df["text"].astype(str).tolist())
68
- labels.extend(df["label"].astype(str).tolist())
69
- else:
70
- return f"File '{file_name}' does not contain required 'text' and 'label' columns."
71
  except Exception as e:
72
- return f"Error reading '{file_name}': {str(e)}"
73
-
74
- if texts and labels:
75
- try:
76
- model.fit(texts, labels)
77
- joblib.dump(model, model_file)
78
- return f"Model trained on {len(texts)} samples from {len(os.listdir(knowledge_base_dir))} files."
79
- except Exception as e:
80
- return f"Error during model training: {str(e)}"
81
- return "No valid training data found in the knowledge base."
82
-
83
- # Chat response function
84
- def respond(message, history, system_message, max_tokens, temperature, top_p):
85
- # Generate response using ML model if possible
86
- model = load_or_initialize_model()
87
 
88
- # Attempt to get a prediction from the ML model
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  try:
 
 
90
  pred_label = model.predict([message])[0]
91
  response = f"Predicted response: {pred_label}"
92
  update_memory(message, response)
 
93
  return response
94
- except Exception:
95
- pass # Continue with GPT model if ML model doesn't have a response
96
 
97
  # Generate response using GPT
98
- messages = [{"role": "system", "content": system_message}]
99
- for turn in history:
100
- if turn["role"] == "user":
101
- messages.append({"role": "user", "content": turn["content"]})
102
- elif turn["role"] == "assistant":
103
- messages.append({"role": "assistant", "content": turn["content"]})
104
- messages.append({"role": "user", "content": message})
105
-
106
- response = ""
107
  try:
 
 
 
 
 
 
108
  for message_part in client.chat_completion(
109
  messages,
110
  max_tokens=max_tokens,
@@ -114,145 +185,177 @@ def respond(message, history, system_message, max_tokens, temperature, top_p):
114
  ):
115
  token = message_part.get("choices", [{}])[0].get("delta", {}).get("content", "")
116
  response += token
 
 
 
 
117
  except Exception as e:
 
118
  response = f"Error generating response: {str(e)}"
119
  update_memory(message, response)
120
  return response
121
 
122
- # Update memory
123
- update_memory(message, response)
124
- return response
125
-
126
- # Gradio interface
127
- with gr.Blocks() as demo:
128
- gr.Markdown("# 🧠 Advanced AI Chatbot with Knowledge Base and Model Training")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
- with gr.Tab("💬 Chat"):
131
- chatbot = gr.Chatbot(label="AI Chatbot", type="messages") # Specify type='messages'
 
 
 
132
 
133
- with gr.Row():
134
- with gr.Column(scale=5): # Changed from 0.85 to 5
135
- user_input = gr.Textbox(
136
- label="Your Message",
137
- placeholder="Type your message here...",
138
- )
139
- with gr.Column(scale=1, min_width=100): # Changed from 0.15 to 1
140
- send_button = gr.Button("Send", variant="primary")
141
- with gr.Row():
142
- system_message = gr.Textbox(
143
- value="You are an advanced AI Chatbot.",
144
- label="System Message",
145
- visible=False # Hidden if default system message is used
146
  )
147
- max_tokens = gr.Slider(
148
- minimum=100, maximum=2048, value=512, step=100, label="Max Tokens"
 
 
149
  )
150
- temperature = gr.Slider(
151
- minimum=0.1, maximum=1.0, value=0.7, step=0.1, label="Temperature"
 
 
 
 
 
 
152
  )
153
- top_p = gr.Slider(
154
- minimum=0.1,
155
- maximum=1.0,
156
- value=0.95,
157
- step=0.05,
158
- label="Top-p (Nucleus Sampling)",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
  )
160
 
161
- def handle_message(message, history, system_message, max_tokens, temperature, top_p):
162
- response = respond(message, history, system_message, max_tokens, temperature, top_p)
163
- history.append({"role": "user", "content": message})
164
- history.append({"role": "assistant", "content": response})
165
- return history, history
166
-
167
- send_button.click(
168
- handle_message,
169
- inputs=[user_input, chatbot, system_message, max_tokens, temperature, top_p],
170
- outputs=[chatbot, chatbot],
171
- )
172
- user_input.submit(
173
- handle_message,
174
- inputs=[user_input, chatbot, system_message, max_tokens, temperature, top_p],
175
- outputs=[chatbot, chatbot],
176
- )
177
-
178
- with gr.Tab("📚 Knowledge Base"):
179
- gr.Markdown("### Manage Knowledge Base")
180
- file_upload = gr.File(
181
- label="Upload CSV File",
182
- file_types=[".csv"],
183
- file_count="single", # Replaced 'multiple=False' with 'file_count="single"'
184
- # Removed 'interactive=True' as it's not a valid parameter
185
- )
186
- upload_output = gr.Textbox(label="Upload Result", interactive=False)
187
- train_button = gr.Button("🔄 Train Model on Knowledge Base")
188
- train_output = gr.Textbox(label="Training Result", interactive=False)
189
-
190
- def upload_file(file):
191
- if file is None:
192
- return "No file uploaded."
193
- try:
194
- # Validate file extension
195
- if not file.name.endswith(".csv"):
196
- return "Invalid file type. Please upload a CSV file."
197
- # Save file to knowledge base directory
198
- destination_path = os.path.join(knowledge_base_dir, file.name)
199
- with open(destination_path, "wb") as f:
200
- f.write(file.read())
201
- return f"File '{file.name}' uploaded successfully."
202
- except Exception as e:
203
- return f"Error uploading file: {str(e)}"
204
-
205
- file_upload.change(upload_file, inputs=file_upload, outputs=upload_output)
206
- train_button.click(train_model_on_files, inputs=None, outputs=train_output)
207
-
208
- with gr.Tab("🧠 Memory"):
209
- gr.Markdown("### View and Manage Conversation Memory")
210
- memory_display = gr.JSON(label="Conversation Memory") # Removed 'interactive=False'
211
- with gr.Row():
212
- refresh_memory = gr.Button("🔄 Refresh Memory")
213
- clear_memory = gr.Button("🗑️ Clear Memory")
214
- export_memory = gr.Button("📤 Export Memory")
215
- export_output = gr.File(label="Download Memory", visible=False)
216
-
217
- def display_memory():
218
- return load_memory()
219
-
220
- def clear_memory_func():
221
- save_memory([])
222
- return []
223
-
224
- def export_memory_func():
225
- if os.path.exists(memory_file):
226
- with open(memory_file, "rb") as f:
227
- return f
228
- return None
229
-
230
- refresh_memory.click(display_memory, inputs=None, outputs=memory_display)
231
- clear_memory.click(clear_memory_func, inputs=None, outputs=memory_display)
232
- export_memory.click(export_memory_func, inputs=None, outputs=export_output)
233
-
234
- with gr.Tab("💾 Download Model"):
235
- gr.Markdown("### Download the Trained Model")
236
- download_button = gr.Button("📥 Download Model")
237
- model_download_output = gr.File(label="Downloadable Model") # Removed 'interactive=False'
238
-
239
- def download_model():
240
- if os.path.exists(model_file):
241
- with open(model_file, "rb") as f:
242
- return f
243
- return None
244
-
245
- download_button.click(download_model, inputs=None, outputs=model_download_output)
246
-
247
- with gr.Tab("⚙️ Settings"):
248
- gr.Markdown("### Application Settings")
249
- # Additional settings can be added here
250
- gr.Textbox(
251
- value="",
252
- label="Settings Placeholder",
253
- placeholder="Add settings here...",
254
- interactive=False, # If 'interactive' is not supported, remove it
255
- )
256
 
 
 
 
257
  if __name__ == "__main__":
258
- demo.launch()
 
 
 
 
 
 
8
  from sklearn.ensemble import RandomForestClassifier
9
  from sklearn.pipeline import Pipeline
10
  import joblib
11
+ import logging
12
+
13
+ # ---------------------------
14
+ # Logging Configuration
15
+ # ---------------------------
16
+ logging.basicConfig(
17
+ filename='app.log',
18
+ filemode='a',
19
+ format='%(asctime)s - %(levelname)s - %(message)s',
20
+ level=logging.INFO
21
+ )
22
+ logger = logging.getLogger(__name__)
23
+
24
+ # ---------------------------
25
+ # Initialize the HuggingFace API Client
26
+ # ---------------------------
27
+ # Replace 'gpt-3.5-turbo' with your desired model. Ensure you have the correct access.
28
+ try:
29
+ client = InferenceClient("gpt-3.5-turbo")
30
+ logger.info("HuggingFace InferenceClient initialized successfully.")
31
+ except Exception as e:
32
+ logger.error(f"Failed to initialize HuggingFace InferenceClient: {e}")
33
+ raise
34
+
35
+ # ---------------------------
36
+ # Persistent Memory and Knowledge Base Setup
37
+ # ---------------------------
38
  memory_file = "chat_memory.json"
39
  knowledge_base_dir = "knowledge_base"
40
  model_file = "chat_model.pkl"
 
42
  # Ensure directories exist
43
  os.makedirs(knowledge_base_dir, exist_ok=True)
44
 
45
+ # ---------------------------
46
+ # Memory Management Functions
47
+ # ---------------------------
48
  def load_memory():
49
+ """Load conversation memory from a JSON file."""
50
+ try:
51
+ if os.path.exists(memory_file):
52
+ with open(memory_file, "r") as f:
53
+ memory = json.load(f)
54
+ logger.info("Conversation memory loaded successfully.")
55
+ return memory
56
+ logger.info("No existing conversation memory found. Starting fresh.")
57
+ return []
58
+ except Exception as e:
59
+ logger.error(f"Error loading memory: {e}")
60
+ return []
61
 
 
62
  def save_memory(memory):
63
+ """Save conversation memory to a JSON file."""
64
+ try:
65
+ with open(memory_file, "w") as f:
66
+ json.dump(memory, f, indent=2)
67
+ logger.info("Conversation memory saved successfully.")
68
+ except Exception as e:
69
+ logger.error(f"Error saving memory: {e}")
70
 
 
71
  def update_memory(message, response):
72
+ """Append user message and assistant response to memory."""
73
+ try:
74
+ memory = load_memory()
75
+ memory.append({"role": "user", "content": message})
76
+ memory.append({"role": "assistant", "content": response})
77
+ # Optionally limit memory size
78
+ if len(memory) > 1000:
79
+ memory = memory[-1000:]
80
+ save_memory(memory)
81
+ except Exception as e:
82
+ logger.error(f"Error updating memory: {e}")
83
+
84
+ # ---------------------------
85
+ # ML Model Management Functions
86
+ # ---------------------------
87
  def load_or_initialize_model():
88
+ """Load the ML model from a file or initialize a new one."""
89
+ try:
90
+ if os.path.exists(model_file):
91
+ model = joblib.load(model_file)
92
+ logger.info("ML model loaded successfully.")
93
+ return model
94
+ model = Pipeline([
95
+ ("vectorizer", CountVectorizer()),
96
+ ("classifier", RandomForestClassifier(n_estimators=100, random_state=42))
97
+ ])
98
+ logger.info("Initialized new ML model pipeline.")
99
+ return model
100
+ except Exception as e:
101
+ logger.error(f"Error loading or initializing model: {e}")
102
+ raise
103
 
104
+ def train_model_on_files():
105
+ """Train the ML model based on CSV files in the knowledge base."""
106
+ try:
107
+ model = load_or_initialize_model()
108
+ texts, labels = [], []
109
+
110
+ # Load data from the knowledge base
111
+ for file_name in os.listdir(knowledge_base_dir):
112
+ file_path = os.path.join(knowledge_base_dir, file_name)
113
+ if file_path.endswith(".csv"):
114
+ try:
115
+ df = pd.read_csv(file_path)
116
+ if "text" in df.columns and "label" in df.columns:
117
+ texts.extend(df["text"].astype(str).tolist())
118
+ labels.extend(df["label"].astype(str).tolist())
119
+ logger.info(f"Loaded data from '{file_name}'.")
120
+ else:
121
+ logger.warning(f"File '{file_name}' is missing 'text' or 'label' columns.")
122
+ return f"File '{file_name}' does not contain required 'text' and 'label' columns."
123
+ except Exception as e:
124
+ logger.error(f"Error reading '{file_name}': {e}")
125
+ return f"Error reading '{file_name}': {str(e)}"
126
+
127
+ if texts and labels:
128
  try:
129
+ model.fit(texts, labels)
130
+ joblib.dump(model, model_file)
131
+ logger.info("ML model trained and saved successfully.")
132
+ return f"Model trained on {len(texts)} samples from {len(os.listdir(knowledge_base_dir))} files."
 
 
133
  except Exception as e:
134
+ logger.error(f"Error during model training: {e}")
135
+ return f"Error during model training: {str(e)}"
136
+ logger.warning("No valid training data found in the knowledge base.")
137
+ return "No valid training data found in the knowledge base."
138
+ except Exception as e:
139
+ logger.error(f"Unexpected error in training model: {e}")
140
+ return f"Unexpected error: {str(e)}"
 
 
 
 
 
 
 
 
141
 
142
+ # ---------------------------
143
+ # Chat Response Function
144
+ # ---------------------------
145
+ def respond(message, history, system_message, max_tokens, temperature, top_p):
146
+ """
147
+ Generate a response to the user's message using the ML model or GPT model.
148
+
149
+ Parameters:
150
+ - message (str): User's input message.
151
+ - history (list): Conversation history.
152
+ - system_message (str): System prompt.
153
+ - max_tokens (int): Maximum number of tokens for GPT response.
154
+ - temperature (float): Sampling temperature for GPT.
155
+ - top_p (float): Nucleus sampling parameter for GPT.
156
+
157
+ Returns:
158
+ - response (str): Generated response.
159
+ """
160
  try:
161
+ # Attempt to get a prediction from the ML model
162
+ model = load_or_initialize_model()
163
  pred_label = model.predict([message])[0]
164
  response = f"Predicted response: {pred_label}"
165
  update_memory(message, response)
166
+ logger.info("Response generated using ML model.")
167
  return response
168
+ except Exception as e:
169
+ logger.info("ML model could not generate a response. Falling back to GPT model.")
170
 
171
  # Generate response using GPT
 
 
 
 
 
 
 
 
 
172
  try:
173
+ messages = [{"role": "system", "content": system_message}]
174
+ for turn in history:
175
+ messages.append({"role": turn["role"], "content": turn["content"]})
176
+ messages.append({"role": "user", "content": message})
177
+
178
+ response = ""
179
  for message_part in client.chat_completion(
180
  messages,
181
  max_tokens=max_tokens,
 
185
  ):
186
  token = message_part.get("choices", [{}])[0].get("delta", {}).get("content", "")
187
  response += token
188
+
189
+ update_memory(message, response)
190
+ logger.info("Response generated using GPT model.")
191
+ return response
192
  except Exception as e:
193
+ logger.error(f"Error generating response with GPT: {e}")
194
  response = f"Error generating response: {str(e)}"
195
  update_memory(message, response)
196
  return response
197
 
198
+ # ---------------------------
199
+ # Gradio Interface
200
+ # ---------------------------
201
+ def create_gradio_interface():
202
+ """Create and configure the Gradio interface."""
203
+ with gr.Blocks() as demo:
204
+ gr.Markdown("# 🧠 Advanced AI Chatbot with Knowledge Base and Model Training")
205
+
206
+ # Chat Tab
207
+ with gr.Tab("💬 Chat"):
208
+ chatbot = gr.Chatbot(label="AI Chatbot", type="messages")
209
+ with gr.Row():
210
+ with gr.Column(scale=5):
211
+ user_input = gr.Textbox(
212
+ label="Your Message",
213
+ placeholder="Type your message here...",
214
+ lines=1
215
+ )
216
+ with gr.Column(scale=1, min_width=100):
217
+ send_button = gr.Button("Send", variant="primary")
218
+ with gr.Row():
219
+ system_message = gr.Textbox(
220
+ value="You are an advanced AI Chatbot.",
221
+ label="System Message",
222
+ visible=False
223
+ )
224
+ max_tokens = gr.Slider(
225
+ minimum=100, maximum=2048, value=512, step=100, label="Max Tokens"
226
+ )
227
+ temperature = gr.Slider(
228
+ minimum=0.1, maximum=1.0, value=0.7, step=0.1, label="Temperature"
229
+ )
230
+ top_p = gr.Slider(
231
+ minimum=0.1,
232
+ maximum=1.0,
233
+ value=0.95,
234
+ step=0.05,
235
+ label="Top-p (Nucleus Sampling)",
236
+ )
237
 
238
+ def handle_message(message, history, system_message, max_tokens, temperature, top_p):
239
+ response = respond(message, history, system_message, max_tokens, temperature, top_p)
240
+ history.append({"role": "user", "content": message})
241
+ history.append({"role": "assistant", "content": response})
242
+ return history, history
243
 
244
+ send_button.click(
245
+ handle_message,
246
+ inputs=[user_input, chatbot, system_message, max_tokens, temperature, top_p],
247
+ outputs=[chatbot, chatbot],
 
 
 
 
 
 
 
 
 
248
  )
249
+ user_input.submit(
250
+ handle_message,
251
+ inputs=[user_input, chatbot, system_message, max_tokens, temperature, top_p],
252
+ outputs=[chatbot, chatbot],
253
  )
254
+
255
+ # Knowledge Base Tab
256
+ with gr.Tab("📚 Knowledge Base"):
257
+ gr.Markdown("### Manage Knowledge Base")
258
+ file_upload = gr.File(
259
+ label="Upload CSV File",
260
+ file_types=[".csv"],
261
+ file_count="single" # Allows only single file upload
262
  )
263
+ upload_output = gr.Textbox(label="Upload Result", interactive=False)
264
+ train_button = gr.Button("🔄 Train Model on Knowledge Base")
265
+ train_output = gr.Textbox(label="Training Result", interactive=False)
266
+
267
+ def upload_file(file):
268
+ if not file:
269
+ return "No file uploaded."
270
+ try:
271
+ # Determine file path and name
272
+ if isinstance(file, dict):
273
+ file_path = file.get('path', '')
274
+ file_name = file.get('name', '')
275
+ else:
276
+ file_path = file
277
+ file_name = os.path.basename(file_path)
278
+
279
+ # Validate file extension
280
+ if not file_name.endswith(".csv"):
281
+ logger.warning(f"Invalid file type attempted: {file_name}")
282
+ return "Invalid file type. Please upload a CSV file."
283
+
284
+ # Save file to knowledge base directory
285
+ destination_path = os.path.join(knowledge_base_dir, file_name)
286
+ shutil.copy(file_path, destination_path)
287
+ logger.info(f"File '{file_name}' uploaded successfully.")
288
+ return f"File '{file_name}' uploaded successfully."
289
+ except Exception as e:
290
+ logger.error(f"Error uploading file: {e}")
291
+ return f"Error uploading file: {str(e)}"
292
+
293
+ file_upload.change(upload_file, inputs=file_upload, outputs=upload_output)
294
+ train_button.click(train_model_on_files, inputs=None, outputs=train_output)
295
+
296
+ # Memory Tab
297
+ with gr.Tab("🧠 Memory"):
298
+ gr.Markdown("### View and Manage Conversation Memory")
299
+ memory_display = gr.JSON(label="Conversation Memory")
300
+ with gr.Row():
301
+ refresh_memory = gr.Button("🔄 Refresh Memory")
302
+ clear_memory = gr.Button("🗑️ Clear Memory")
303
+ export_memory = gr.Button("📤 Export Memory")
304
+ export_output = gr.File(label="Download Memory", visible=False)
305
+
306
+ def display_memory():
307
+ return load_memory()
308
+
309
+ def clear_memory_func():
310
+ try:
311
+ save_memory([])
312
+ logger.info("Conversation memory cleared.")
313
+ return []
314
+ except Exception as e:
315
+ logger.error(f"Error clearing memory: {e}")
316
+ return f"Error clearing memory: {str(e)}"
317
+
318
+ def export_memory_func():
319
+ if os.path.exists(memory_file):
320
+ return memory_file # Gradio will handle the download
321
+ return "No memory file found."
322
+
323
+ refresh_memory.click(display_memory, inputs=None, outputs=memory_display)
324
+ clear_memory.click(clear_memory_func, inputs=None, outputs=memory_display)
325
+ export_memory.click(export_memory_func, inputs=None, outputs=export_output)
326
+
327
+ # Download Model Tab
328
+ with gr.Tab("💾 Download Model"):
329
+ gr.Markdown("### Download the Trained Model")
330
+ download_button = gr.Button("📥 Download Model")
331
+ model_download_output = gr.File(label="Downloadable Model")
332
+
333
+ def download_model():
334
+ if os.path.exists(model_file):
335
+ return model_file # Gradio will handle the file download
336
+ return "No trained model found."
337
+
338
+ download_button.click(download_model, inputs=None, outputs=model_download_output)
339
+
340
+ # Settings Tab
341
+ with gr.Tab("⚙️ Settings"):
342
+ gr.Markdown("### Application Settings")
343
+ gr.Textbox(
344
+ value="",
345
+ label="Settings Placeholder",
346
+ placeholder="Add settings here..."
347
+ # Removed 'interactive' parameter as it's unsupported
348
  )
349
 
350
+ return demo
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
351
 
352
+ # ---------------------------
353
+ # Main Execution
354
+ # ---------------------------
355
  if __name__ == "__main__":
356
+ try:
357
+ interface = create_gradio_interface()
358
+ logger.info("Launching Gradio interface.")
359
+ interface.launch()
360
+ except Exception as e:
361
+ logger.critical(f"Application failed to start: {e}")