acecalisto3 commited on
Commit
2853bae
Β·
verified Β·
1 Parent(s): c19dd51

Update app2.py

Browse files
Files changed (1) hide show
  1. app2.py +323 -4
app2.py CHANGED
@@ -27,6 +27,8 @@ import numpy as np
27
  import tarfile
28
  import gzip
29
  import math
 
 
30
 
31
  # Setup enhanced logging with more detailed formatting
32
  logging.basicConfig(
@@ -1132,6 +1134,281 @@ def generate_qr_codes(data: Union[str, Dict, List], combined: bool = True) -> Li
1132
  # process_inputs function already handles calling them and getting
1133
  # the combined list of results.
1134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1135
  def create_modern_interface():
1136
  """Create a modern and visually appealing Gradio interface"""
1137
 
@@ -1268,6 +1545,7 @@ def create_modern_interface():
1268
  )
1269
 
1270
  qr_code_paths = gr.State([])
 
1271
  gr.Markdown("""
1272
  # 🌐 Advanced Data Processing & QR Code Generator
1273
  Transform your data into beautifully designed, sequenced QR codes with our cutting-edge processor.
@@ -1322,6 +1600,15 @@ def create_modern_interface():
1322
  viewport_output = gr.HTML(label="QR Code Sequence Viewport")
1323
  enabled_qr_codes = gr.State([]) # To store the enabled/disabled state
1324
 
 
 
 
 
 
 
 
 
 
1325
  # Load example data
1326
  def load_example():
1327
  example = {
@@ -1353,7 +1640,7 @@ def create_modern_interface():
1353
  return json.dumps(example, indent=2)
1354
 
1355
  def clear_input():
1356
- return "", None, "" # Clear url, files, text
1357
 
1358
  def update_viewport(paths, enabled_states):
1359
  if not paths:
@@ -1478,10 +1765,12 @@ def create_modern_interface():
1478
  logger.error(f"Overall processing error in process_inputs: {e}")
1479
  processing_status_messages.append(f"❌ An unexpected error occurred during processing: {str(e)}")
1480
 
 
1481
  return (
1482
  final_json_output,
1483
  [str(path) for path in qr_paths], # Gradio Gallery expects list of paths (strings)
1484
- "\n".join(processing_status_messages) # Join status messages
 
1485
  )
1486
 
1487
  def on_qr_generation(qr_paths_list):
@@ -1497,12 +1786,12 @@ def create_modern_interface():
1497
 
1498
  # Link events
1499
  example_btn.click(load_example, inputs=[], outputs=text_input)
1500
- clear_btn.click(clear_input, inputs=[], outputs=[url_input, file_input, text_input]) # Clear all inputs
1501
 
1502
  process_btn.click(
1503
  process_inputs,
1504
  inputs=[url_input, file_input, text_input, combine_data, crawl_depth_slider], # Pass crawl_depth_slider value
1505
- outputs=[output_json, output_gallery, output_text]
1506
  ).then( # Chain a .then() to update the QR paths state and trigger viewport update
1507
  on_qr_generation,
1508
  inputs=[output_gallery], # Get the list of paths from the gallery output
@@ -1512,6 +1801,34 @@ def create_modern_interface():
1512
  # The viewport tab's select event will trigger update_viewport to render the grid
1513
  viewport_tab.select(update_viewport, inputs=[qr_code_paths, enabled_qr_codes], outputs=[viewport_output])
1514
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1515
  # Add helpful documentation
1516
  gr.Markdown("""
1517
  ### πŸš€ Features
@@ -1524,6 +1841,7 @@ def create_modern_interface():
1524
  - **Sequential QR Codes**: Maintains data integrity across multiple codes by chunking the combined/individual processed data.
1525
  - **QR Code Viewport**: Visualize generated QR codes in a sequenced square grid with options to enable/disable individual codes for selective scanning/sharing.
1526
  - **Modern Design**: Clean, responsive interface with visual feedback.
 
1527
  ### πŸ’‘ Tips
1528
  1. **URLs**: Enter multiple URLs separated by commas or newlines. The processor will attempt to fetch and structure the content based on its type, following links up to the specified **Crawl Depth**.
1529
  2. **Files**: Upload any type of file. The processor will attempt to handle supported text-based files, archives (.zip, .tar, .gz), and specific document/structured formats.
@@ -1532,6 +1850,7 @@ def create_modern_interface():
1532
  5. **QR Codes**: Choose whether to "Combine all data into sequence" or generate separate sequences for each input item.
1533
  6. **Processing**: Monitor the "Processing Status" box for real-time updates and notes about errors or processing steps.
1534
  7. **Output**: The "Processed Data" JSON box shows the structured data extracted from your inputs. The "Generated QR Codes" gallery shows the QR code images.
 
1535
  ### βš™οΈ QR Code Viewport Instructions
1536
  1. Navigate to the **QR Code Viewport** tab after generating QR codes.
1537
  2. The generated QR codes will be displayed in a grid based on their total count.
 
27
  import tarfile
28
  import gzip
29
  import math
30
+ import random # Added for dummy chatbot response variation
31
+ import pandas as pd # Added for potential data analysis
32
 
33
  # Setup enhanced logging with more detailed formatting
34
  logging.basicConfig(
 
1134
  # process_inputs function already handles calling them and getting
1135
  # the combined list of results.
1136
 
1137
+ # --- Chatbot Logic ---
1138
+ def respond_to_chat(message: str, chat_history: List[Tuple[str, str]], chatbot_data: Optional[List[Dict]]) -> Tuple[List[Tuple[str, str]], List[Dict]]:
1139
+ """Responds to user chat messages based on the loaded JSON data."""
1140
+ if chatbot_data is None or not chatbot_data:
1141
+ chat_history.append((message, "Please process some data first using the other tabs before chatting."))
1142
+ return chat_history, chatbot_data
1143
+
1144
+ # Add user message to history
1145
+ chat_history.append((message, "")) # Add empty string for bot response initially
1146
+
1147
+ response = ""
1148
+ lower_message = message.lower().strip()
1149
+
1150
+ try:
1151
+ # Attempt to flatten the data structure for easier querying if it's nested
1152
+ # This is a simplified approach; a real implementation might need a more
1153
+ # sophisticated data traversal/query engine.
1154
+ flat_data = []
1155
+ for item in chatbot_data:
1156
+ # Recursively flatten dictionaries and lists within the item
1157
+ def flatten_item(d, parent_key='', sep='_'):
1158
+ items = []
1159
+ for k, v in d.items():
1160
+ new_key = parent_key + sep + k if parent_key else k
1161
+ if isinstance(v, dict):
1162
+ items.extend(flatten_item(v, new_key, sep=sep).items())
1163
+ elif isinstance(v, list):
1164
+ # Flatten lists by processing each element
1165
+ for i, elem in enumerate(v):
1166
+ if isinstance(elem, (dict, list)):
1167
+ items.extend(flatten_item({f'{new_key}_{i}': elem}, sep=sep).items())
1168
+ else:
1169
+ items.append((f'{new_key}_{i}', elem))
1170
+ else:
1171
+ items.append((new_key, v))
1172
+ return dict(items)
1173
+
1174
+ if isinstance(item, dict):
1175
+ flat_data.append(flatten_item(item))
1176
+ elif isinstance(item, list):
1177
+ # If a top-level item is a list, try flattening its elements
1178
+ for sub_item in item:
1179
+ if isinstance(sub_item, dict):
1180
+ flat_data.append(flatten_item(sub_item))
1181
+ else:
1182
+ # Handle non-dict items in the top-level list if necessary
1183
+ flat_data.append({'value': sub_item}) # Wrap in dict
1184
+
1185
+
1186
+ # Use pandas DataFrame for easier querying and analysis if flat_data is suitable
1187
+ df = None
1188
+ if flat_data:
1189
+ try:
1190
+ # Attempt to create a DataFrame. This might fail if structures are highly inconsistent.
1191
+ df = pd.DataFrame(flat_data)
1192
+ logger.debug(f"Created DataFrame with shape: {df.shape}")
1193
+ logger.debug(f"DataFrame columns: {list(df.columns)}")
1194
+ except Exception as e:
1195
+ logger.warning(f"Could not create pandas DataFrame from processed data: {e}. Falling back to manual processing.")
1196
+ df = None # Ensure df is None if creation failed
1197
+
1198
+
1199
+ # --- Complex Queries and Analysis ---
1200
+
1201
+ if df is not None:
1202
+ # Example: How many unique values in a column?
1203
+ match = re.search(r'how many unique values in (\w+)', lower_message)
1204
+ if match:
1205
+ column_name = match.group(1)
1206
+ if column_name in df.columns:
1207
+ unique_count = df[column_name].nunique()
1208
+ response = f"There are {unique_count} unique values in the '{column_name}' column."
1209
+ else:
1210
+ response = f"I couldn't find a column named '{column_name}' in the data. Available columns are: {', '.join(df.columns)}"
1211
+
1212
+ # Example: What is the average/sum/min/max of a numeric column?
1213
+ match = re.search(r'what is the (average|sum|min|max) of (\w+)', lower_message)
1214
+ if match:
1215
+ operation, column_name = match.groups()
1216
+ if column_name in df.columns:
1217
+ try:
1218
+ # Attempt to convert column to numeric, coercing errors
1219
+ numeric_col = pd.to_numeric(df[column_name], errors='coerce')
1220
+ # Drop NaNs that resulted from coercion
1221
+ numeric_col = numeric_col.dropna()
1222
+
1223
+ if not numeric_col.empty:
1224
+ if operation == 'average':
1225
+ result = numeric_col.mean()
1226
+ response = f"The average of '{column_name}' is {result:.2f}."
1227
+ elif operation == 'sum':
1228
+ result = numeric_col.sum()
1229
+ response = f"The sum of '{column_name}' is {result:.2f}."
1230
+ elif operation == 'min':
1231
+ result = numeric_col.min()
1232
+ response = f"The minimum of '{column_name}' is {result}."
1233
+ elif operation == 'max':
1234
+ result = numeric_col.max()
1235
+ response = f"The maximum of '{column_name}' is {result}."
1236
+ else:
1237
+ response = "I can calculate average, sum, min, or max."
1238
+ else:
1239
+ response = f"The column '{column_name}' does not contain numeric values that I can analyze."
1240
+ except Exception as e:
1241
+ response = f"An error occurred while calculating the {operation} of '{column_name}': {e}"
1242
+ logger.error(f"Error calculating {operation} for column '{column_name}': {e}")
1243
+ else:
1244
+ response = f"I couldn't find a column named '{column_name}'. Available columns are: {', '.join(df.columns)}"
1245
+
1246
+ # Example: Filter data based on a simple condition (e.g., price > 100)
1247
+ match = re.search(r'show me items where (\w+)\s*([<>=!]+)\s*(\w+)', lower_message)
1248
+ if match:
1249
+ column_name, operator, value_str = match.groups()
1250
+ try:
1251
+ # Attempt to infer value type (numeric, string)
1252
+ try:
1253
+ value = float(value_str)
1254
+ is_numeric_comparison = True
1255
+ except ValueError:
1256
+ value = value_str.strip("'\"") # Remove quotes for string comparison
1257
+ is_numeric_comparison = False
1258
+
1259
+ if column_name in df.columns:
1260
+ if is_numeric_comparison:
1261
+ # Ensure the column is numeric for comparison
1262
+ numeric_col = pd.to_numeric(df[column_name], errors='coerce')
1263
+ filtered_df = df.loc[pd.notna(numeric_col)] # Filter out rows where conversion failed
1264
+
1265
+ if operator == '>':
1266
+ filtered_results = filtered_df[numeric_col > value]
1267
+ elif operator == '<':
1268
+ filtered_results = filtered_df[numeric_col < value]
1269
+ elif operator == '>=':
1270
+ filtered_results = filtered_df[numeric_col >= value]
1271
+ elif operator == '<=':
1272
+ filtered_results = filtered_df[numeric_col <= value]
1273
+ elif operator == '==':
1274
+ filtered_results = filtered_df[numeric_col == value]
1275
+ elif operator == '!=':
1276
+ filtered_results = filtered_df[numeric_col != value]
1277
+ else:
1278
+ filtered_results = pd.DataFrame() # Empty if operator is not recognized
1279
+ response = f"Unsupported numeric operator: {operator}. Try >, <, >=, <=, ==, !=."
1280
+
1281
+ if not filtered_results.empty:
1282
+ preview = filtered_results.to_json(orient='records', indent=2)[:500] + "..." if len(filtered_results.to_json()) > 500 else filtered_results.to_json(orient='records', indent=2)
1283
+ response = f"Here are the items where '{column_name}' {operator} {value_str}:\n```json\n{preview}\n```"
1284
+ elif 'response' not in locals(): # Only set if not already set by unsupported operator
1285
+ response = f"No items found where '{column_name}' {operator} {value_str}."
1286
+
1287
+ elif operator == '==': # Simple string equality
1288
+ filtered_results = df[df[column_name] == value]
1289
+ if not filtered_results.empty:
1290
+ preview = filtered_results.to_json(orient='records', indent=2)[:500] + "..." if len(filtered_results.to_json()) > 500 else filtered_results.to_json(orient='records', indent=2)
1291
+ response = f"Here are the items where '{column_name}' is '{value}':\n```json\n{preview}\n```"
1292
+ else:
1293
+ response = f"No items found where '{column_name}' is '{value}'."
1294
+ elif operator == '!=': # Simple string inequality
1295
+ filtered_results = df[df[column_name] != value]
1296
+ if not filtered_results.empty:
1297
+ preview = filtered_results.to_json(orient='records', indent=2)[:500] + "..." if len(filtered_results.to_json()) > 500 else filtered_results.to_json(orient='records', indent=2)
1298
+ response = f"Here are the items where '{column_name}' is not '{value}':\n```json\n{preview}\n```"
1299
+ else:
1300
+ response = f"All items have '{column_name}' as '{value}' or the column doesn't exist."
1301
+ else:
1302
+ response = f"Unsupported operator for string comparison: {operator}. Try == or !=."
1303
+
1304
+
1305
+ else:
1306
+ response = f"I couldn't find a column named '{column_name}'. Available columns are: {', '.join(df.columns)}"
1307
+
1308
+ except Exception as e:
1309
+ response = f"An error occurred while filtering data: {e}"
1310
+ logger.error(f"Error filtering data based on condition: {e}")
1311
+
1312
+
1313
+ # --- General Queries ---
1314
+
1315
+ if not response: # If no specific analysis/query matched yet
1316
+ if "how many items" in lower_message or "number of items" in lower_message:
1317
+ if isinstance(chatbot_data, list):
1318
+ response = f"There are {len(chatbot_data)} top-level items in the processed data."
1319
+ elif isinstance(chatbot_data, dict):
1320
+ response = "The processed data is a single dictionary, not a list of items."
1321
+ else:
1322
+ response = "The processed data is not a standard list or dictionary structure."
1323
+
1324
+ elif "what is the structure" in lower_message or "tell me about the data" in lower_message:
1325
+ if isinstance(chatbot_data, list) and chatbot_data:
1326
+ sample_item = chatbot_data[0]
1327
+ response = f"The data is a list containing {len(chatbot_data)} items. The first item has the following top-level keys: {list(sample_item.keys())}. I can try to tell you more about specific keys if you like."
1328
+ elif isinstance(chatbot_data, dict):
1329
+ response = f"The data is a dictionary with the following top-level keys: {list(chatbot_data.keys())}."
1330
+ else:
1331
+ response = "The processed data is not a standard list or dictionary structure that I can easily describe."
1332
+
1333
+ elif "show me" in lower_message or "get me" in lower_message or "extract" in lower_message:
1334
+ # Basic extraction if DataFrame wasn't created or query wasn't complex
1335
+ parts = lower_message.split("show me")
1336
+ if len(parts) > 1:
1337
+ key_request = parts[1].strip().split(" ")[0]
1338
+ extracted_values = []
1339
+ if isinstance(chatbot_data, list):
1340
+ for item in chatbot_data:
1341
+ if isinstance(item, dict) and key_request in item:
1342
+ extracted_values.append(item[key_request])
1343
+ elif isinstance(chatbot_data, dict) and key_request in chatbot_data:
1344
+ extracted_values.append(chatbot_data[key_request])
1345
+
1346
+ if extracted_values:
1347
+ preview = json.dumps(extracted_values, indent=2)[:500] + "..." if len(json.dumps(extracted_values)) > 500 else json.dumps(extracted_values, indent=2)
1348
+ response = f"Here are the values for '{key_request}':\n```json\n{preview}\n```"
1349
+ else:
1350
+ response = f"I couldn't find a key named '{key_request}' in the top level of the data items."
1351
+ else:
1352
+ response = "What specifically would you like me to show or extract?"
1353
+
1354
+ # --- Speculation about Modifications ---
1355
+ elif "how can i modify" in lower_message or "how to change" in lower_message or "can i add" in lower_message or "can i remove" in lower_message:
1356
+ response = "I cannot directly modify the data here, but I can tell you how you *could* modify it. What kind of change are you considering (e.g., adding an item, changing a value, removing a field)?"
1357
+
1358
+ elif "add a field" in lower_message or "add a column" in lower_message:
1359
+ response = "To add a field (or column if the data is tabular), you would typically iterate through each item (or row) in the data and add the new key-value pair. For example, adding a 'status' field with a default value."
1360
+
1361
+ elif "change a value" in lower_message or "update a field" in lower_message:
1362
+ response = "To change a value, you would need to identify the specific item(s) and the field you want to update. You could use a condition (like filtering) to find the right items and then assign a new value to the field."
1363
+
1364
+ elif "remove a field" in lower_message or "delete a column" in lower_message:
1365
+ response = "To remove a field, you would iterate through each item and delete the specified key. Be careful, as this is irreversible."
1366
+
1367
+ elif "restructure" in lower_message or "change the format" in lower_message:
1368
+ response = "Restructuring data involves transforming it into a different shape. This could mean flattening nested objects, grouping items, or pivoting data. This often requires writing custom code to map the old structure to the new one."
1369
+
1370
+ elif "what if i" in lower_message or "if i changed" in lower_message:
1371
+ response = "Tell me what specific change you're contemplating, and I can speculate on the potential impact or how you might approach it programmatically."
1372
+
1373
+
1374
+ # --- General Conversation / Fallback ---
1375
+ elif "hello" in lower_message or "hi" in lower_message:
1376
+ response = random.choice(["Hello! How can I help you understand the processed data?", "Hi there! What's on your mind about this data?", "Hey! Ask me anything about the data you've loaded."])
1377
+
1378
+ elif "thank you" in lower_message or "thanks" in lower_message:
1379
+ response = random.choice(["You're welcome!", "Glad I could help.", "No problem! Let me know if you have more questions about the data."])
1380
+
1381
+ elif "clear chat" in lower_message:
1382
+ chat_history = [] # Clear history
1383
+ response = "Chat history cleared."
1384
+
1385
+ elif not response: # If still no specific response matched
1386
+ response = random.choice([
1387
+ "I can analyze the data you've processed. What would you like to know?",
1388
+ "Ask me about the number of items, the structure, or values of specific fields.",
1389
+ "I can perform basic analysis like counting unique values or calculating sums/averages if the data is suitable.",
1390
+ "Tell me what you want to extract or filter from the data.",
1391
+ "I'm still learning, but I can try to answer questions about the data structure and content."
1392
+ ])
1393
+
1394
+ except Exception as e:
1395
+ logger.error(f"Chatbot runtime error: {e}")
1396
+ response = f"An internal error occurred while processing your request: {e}"
1397
+ response += "\nPlease try rephrasing your question or clear the chat history."
1398
+
1399
+
1400
+ # Update the last message in history with the bot's response
1401
+ if chat_history and chat_history[-1][1] == "":
1402
+ chat_history[-1] = (chat_history[-1][0], response)
1403
+ else:
1404
+ # This case should ideally not happen if the initial append was done correctly
1405
+ chat_history.append(("", response)) # Append bot response if something went wrong with initial append
1406
+
1407
+
1408
+ return chat_history, chatbot_data # Return updated history and data state
1409
+
1410
+
1411
+ # --- Gradio Interface Definition ---
1412
  def create_modern_interface():
1413
  """Create a modern and visually appealing Gradio interface"""
1414
 
 
1545
  )
1546
 
1547
  qr_code_paths = gr.State([])
1548
+ chatbot_data = gr.State(None) # State to hold the processed JSON data for the chatbot
1549
  gr.Markdown("""
1550
  # 🌐 Advanced Data Processing & QR Code Generator
1551
  Transform your data into beautifully designed, sequenced QR codes with our cutting-edge processor.
 
1600
  viewport_output = gr.HTML(label="QR Code Sequence Viewport")
1601
  enabled_qr_codes = gr.State([]) # To store the enabled/disabled state
1602
 
1603
+ with gr.Tab("πŸ€– Chat with Data") as chat_tab:
1604
+ chat_history = gr.State([]) # State to hold chat history
1605
+ chatbot = gr.Chatbot(label="Data Chatbot")
1606
+ with gr.Row():
1607
+ chat_input = gr.Textbox(label="Your Message", placeholder="Ask me about the processed data...")
1608
+ send_msg_btn = gr.Button("Send")
1609
+ clear_chat_btn = gr.Button("Clear Chat History")
1610
+
1611
+
1612
  # Load example data
1613
  def load_example():
1614
  example = {
 
1640
  return json.dumps(example, indent=2)
1641
 
1642
  def clear_input():
1643
+ return "", None, "", None # Clear url, files, text, and chatbot data state
1644
 
1645
  def update_viewport(paths, enabled_states):
1646
  if not paths:
 
1765
  logger.error(f"Overall processing error in process_inputs: {e}")
1766
  processing_status_messages.append(f"❌ An unexpected error occurred during processing: {str(e)}")
1767
 
1768
+ # Return processed data for the chatbot state
1769
  return (
1770
  final_json_output,
1771
  [str(path) for path in qr_paths], # Gradio Gallery expects list of paths (strings)
1772
+ "\n".join(processing_status_messages), # Join status messages
1773
+ final_json_output # Pass the processed data to the chatbot_data state
1774
  )
1775
 
1776
  def on_qr_generation(qr_paths_list):
 
1786
 
1787
  # Link events
1788
  example_btn.click(load_example, inputs=[], outputs=text_input)
1789
+ clear_btn.click(clear_input, inputs=[], outputs=[url_input, file_input, text_input, chatbot_data]) # Clear all inputs including chatbot data state
1790
 
1791
  process_btn.click(
1792
  process_inputs,
1793
  inputs=[url_input, file_input, text_input, combine_data, crawl_depth_slider], # Pass crawl_depth_slider value
1794
+ outputs=[output_json, output_gallery, output_text, chatbot_data] # Output to chatbot_data state
1795
  ).then( # Chain a .then() to update the QR paths state and trigger viewport update
1796
  on_qr_generation,
1797
  inputs=[output_gallery], # Get the list of paths from the gallery output
 
1801
  # The viewport tab's select event will trigger update_viewport to render the grid
1802
  viewport_tab.select(update_viewport, inputs=[qr_code_paths, enabled_qr_codes], outputs=[viewport_output])
1803
 
1804
+ # Chatbot interactions
1805
+ send_msg_btn.click(
1806
+ respond_to_chat,
1807
+ inputs=[chat_input, chat_history, chatbot_data], # Pass chatbot_data state
1808
+ outputs=[chatbot, chatbot_data] # Update chatbot display and chatbot_data state
1809
+ ).then(
1810
+ lambda: "", # Clear the input box after sending
1811
+ inputs=None,
1812
+ outputs=chat_input
1813
+ )
1814
+
1815
+ chat_input.submit( # Allow sending message by pressing Enter
1816
+ respond_to_chat,
1817
+ inputs=[chat_input, chat_history, chatbot_data], # Pass chatbot_data state
1818
+ outputs=[chatbot, chatbot_data] # Update chatbot display and chatbot_data state
1819
+ ).then(
1820
+ lambda: "", # Clear the input box after sending
1821
+ inputs=None,
1822
+ outputs=chat_input
1823
+ )
1824
+
1825
+ clear_chat_btn.click(
1826
+ lambda: [], # Clear chat history
1827
+ inputs=None,
1828
+ outputs=chatbot
1829
+ )
1830
+
1831
+
1832
  # Add helpful documentation
1833
  gr.Markdown("""
1834
  ### πŸš€ Features
 
1841
  - **Sequential QR Codes**: Maintains data integrity across multiple codes by chunking the combined/individual processed data.
1842
  - **QR Code Viewport**: Visualize generated QR codes in a sequenced square grid with options to enable/disable individual codes for selective scanning/sharing.
1843
  - **Modern Design**: Clean, responsive interface with visual feedback.
1844
+ - **Data Chatbot**: Interact conversationally with the processed JSON data to ask questions about its structure, content, or request specific information.
1845
  ### πŸ’‘ Tips
1846
  1. **URLs**: Enter multiple URLs separated by commas or newlines. The processor will attempt to fetch and structure the content based on its type, following links up to the specified **Crawl Depth**.
1847
  2. **Files**: Upload any type of file. The processor will attempt to handle supported text-based files, archives (.zip, .tar, .gz), and specific document/structured formats.
 
1850
  5. **QR Codes**: Choose whether to "Combine all data into sequence" or generate separate sequences for each input item.
1851
  6. **Processing**: Monitor the "Processing Status" box for real-time updates and notes about errors or processing steps.
1852
  7. **Output**: The "Processed Data" JSON box shows the structured data extracted from your inputs. The "Generated QR Codes" gallery shows the QR code images.
1853
+ 8. **Chatbot**: After processing data, go to the "Chat with Data" tab to ask questions about the JSON output.
1854
  ### βš™οΈ QR Code Viewport Instructions
1855
  1. Navigate to the **QR Code Viewport** tab after generating QR codes.
1856
  2. The generated QR codes will be displayed in a grid based on their total count.