Vardhan-kuppala commited on
Commit
abf8cf8
·
verified ·
1 Parent(s): 164887a

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +557 -0
  2. requirements.txt +14 -0
  3. test_data.xlsx +0 -0
app.py ADDED
@@ -0,0 +1,557 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ from typing import List, Dict, Tuple, Optional
5
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
6
+ from langchain_community.embeddings import HuggingFaceEmbeddings
7
+ from langchain.memory import ConversationBufferMemory
8
+ from langchain_community.vectorstores import FAISS
9
+ from langchain.docstore.document import Document
10
+ from langchain_huggingface import HuggingFaceEndpoint
11
+ from langchain.chains import ConversationalRetrievalChain
12
+ from langchain.prompts import PromptTemplate
13
+ import os
14
+
15
+ # Configuration
16
+ MODEL_NAME = "mistralai/Mistral-7B-Instruct-v0.2"
17
+ api_token = os.getenv("HF_TOKEN")
18
+
19
+ # Define system message for consistent LLM behavior
20
+ SYSTEM_MESSAGE = """You are a microcontroller selection expert assistant. Your task is to:
21
+ 1. Analyze user requirements carefully
22
+ 2. Compare available microcontrollers based on ALL provided specifications
23
+ 3. Recommend the best matches with detailed explanations
24
+ 4. Consider trade-offs between different features
25
+ 5. Highlight any potential concerns or limitations
26
+
27
+ When making recommendations:
28
+ - Always mention specific model numbers and their key features
29
+ - Explain why each recommendation matches the requirements
30
+ - Compare pros and cons between recommendations
31
+ - Note any missing specifications that might be important"""
32
+
33
+ # Custom prompt templates
34
+ CONDENSE_QUESTION_PROMPT = PromptTemplate.from_template("""
35
+ Given the following conversation and a follow up question, rephrase the follow up question to be a standalone question that captures all relevant context from the conversation.
36
+
37
+ Chat History:
38
+ {chat_history}
39
+
40
+ Follow Up Input: {question}
41
+
42
+ Standalone question:""")
43
+
44
+ QA_PROMPT = PromptTemplate.from_template("""
45
+ {system_message}
46
+
47
+ Context information from microcontroller database:
48
+ {context}
49
+
50
+ User Query: {question}
51
+
52
+ Provide a detailed response following these steps:
53
+ 1. Analyze Requirements: Clearly state the key requirements from the query
54
+ 2. Matching Products: List and compare the best matching microcontrollers
55
+ 3. Feature Analysis: Detail how each recommended product meets the requirements
56
+ 4. Trade-offs: Explain any compromises or trade-offs
57
+ 5. Additional Considerations: Mention any important factors the user should consider
58
+
59
+ Response:""")
60
+
61
+ def validate_excel_format(df: pd.DataFrame) -> bool:
62
+ """Validate if Excel file has required specifications as columns"""
63
+ expected_specs = [
64
+ 'Product ID', 'Product Title', 'PLP', 'Bit Size', 'cpu',
65
+ 'Program Memory (KB)', 'Data Flash (KB)', 'RAM (KB)',
66
+ 'Lead Count (#)', 'Supply Voltage (V)', 'Operating Freq (Max) (MHz)',
67
+ 'RTC', 'LVD or PVD', 'DMA', 'I/O Ports', 'Timer', 'ADC', 'DAC',
68
+ 'Ethernet', 'USB', 'UART', 'SPI', 'I2C', 'CAN', 'LIN',
69
+ 'Human machine interface', 'pkg.Type', 'Temp.Range'
70
+ ]
71
+
72
+ # Check if at least the essential columns exist
73
+ essential_specs = ['Product ID', 'Product Title', 'Bit Size', 'cpu']
74
+ missing_essential = [col for col in essential_specs if col not in df.columns]
75
+
76
+ if missing_essential:
77
+ print(f"Missing essential columns: {missing_essential}")
78
+ return False
79
+
80
+ # Print found and missing columns for debugging
81
+ found_specs = [col for col in expected_specs if col in df.columns]
82
+ missing_specs = [col for col in expected_specs if col not in df.columns]
83
+
84
+ print("Found specifications:", found_specs)
85
+ print("Missing specifications:", missing_specs)
86
+
87
+ return True
88
+
89
+
90
+ def normalize_column_name(col_name: str) -> str:
91
+ """Normalize column names to handle different variations"""
92
+ # Convert to lowercase and remove special characters
93
+ normalized = str(col_name).lower().strip()
94
+ normalized = ''.join(c for c in normalized if c.isalnum() or c.isspace())
95
+
96
+ # Common variations mapping
97
+ variations = {
98
+ 'productid': 'Product ID',
99
+ 'producttitle': 'Product Title',
100
+ 'programmemorykb': 'Program Memory (KB)',
101
+ 'programmemory': 'Program Memory (KB)',
102
+ 'flashmemory': 'Program Memory (KB)',
103
+ 'dataflashkb': 'Data Flash (KB)',
104
+ 'dataflash': 'Data Flash (KB)',
105
+ 'ramkb': 'RAM (KB)',
106
+ 'ram': 'RAM (KB)',
107
+ 'bitsize': 'Bit Size',
108
+ 'cpucore': 'cpu',
109
+ 'processor': 'cpu',
110
+ 'supplyvoltage': 'Supply Voltage (V)',
111
+ 'voltage': 'Supply Voltage (V)',
112
+ 'operatingfreq': 'Operating Freq (Max) (MHz)',
113
+ 'frequency': 'Operating Freq (Max) (MHz)',
114
+ 'maxfreq': 'Operating Freq (Max) (MHz)',
115
+ 'leadcount': 'Lead Count (#)',
116
+ 'pins': 'Lead Count (#)',
117
+ 'pincount': 'Lead Count (#)',
118
+ 'interface': 'I/O Ports',
119
+ 'ioports': 'I/O Ports',
120
+ 'packagetype': 'pkg.Type',
121
+ 'package': 'pkg.Type',
122
+ 'temprange': 'Temp.Range',
123
+ 'temperature': 'Temp.Range',
124
+ 'humanmachineinterface': 'Human machine interface',
125
+ 'hmi': 'Human machine interface'
126
+ }
127
+
128
+ # Return original if no mapping found
129
+ return variations.get(normalized.replace(' ', ''), col_name)
130
+
131
+ def validate_and_map_columns(df: pd.DataFrame) -> Tuple[pd.DataFrame, Dict[str, str]]:
132
+ """Validate and map Excel columns to standard names"""
133
+ # Create mapping of found columns
134
+ column_mapping = {}
135
+ new_columns = []
136
+
137
+ for col in df.columns:
138
+ normalized_name = normalize_column_name(col)
139
+ column_mapping[col] = normalized_name
140
+ new_columns.append(normalized_name)
141
+
142
+ # Rename columns in DataFrame
143
+ df.columns = new_columns
144
+
145
+ # Print found specifications for debugging
146
+ print("Found specifications:", new_columns)
147
+
148
+ return df, column_mapping
149
+
150
+
151
+ def clean_excel_data(df: pd.DataFrame) -> pd.DataFrame:
152
+ """Clean and prepare Excel data with flexible handling"""
153
+ # Replace various forms of empty/NA values
154
+ df = df.replace([np.nan, 'N/A', 'NA', '-', 'None', 'none', 'nil', 'NIL'], '')
155
+
156
+ # Numeric columns with their units
157
+ numeric_specs = {
158
+ 'Program Memory (KB)': 'KB',
159
+ 'Data Flash (KB)': 'KB',
160
+ 'RAM (KB)': 'KB',
161
+ 'Lead Count (#)': '',
162
+ 'Supply Voltage (V)': 'V',
163
+ 'Operating Freq (Max) (MHz)': 'MHz'
164
+ }
165
+
166
+ # Process each numeric column if it exists
167
+ for col, unit in numeric_specs.items():
168
+ if col in df.columns:
169
+ # Extract numeric values from string if needed
170
+ df[col] = df[col].astype(str).str.extract(r'(\d+\.?\d*)').astype(float)
171
+
172
+ # Clean boolean/feature columns
173
+ feature_cols = ['RTC', 'DMA', 'Ethernet', 'USB', 'UART', 'SPI', 'I2C', 'CAN', 'LIN']
174
+ for col in feature_cols:
175
+ if col in df.columns:
176
+ df[col] = df[col].astype(str).str.lower()
177
+ # Map various positive indicators to 'Yes'
178
+ df[col] = df[col].apply(lambda x: 'Yes' if x in ['yes', 'y', '1', 'true', 'available', 'supported', '✓', '√'] else 'No')
179
+
180
+ return df
181
+
182
+ def process_mc_excel(excel_file: str) -> Tuple[List[Document], Optional[str]]:
183
+ """Convert microcontroller Excel data to Document objects with flexible handling"""
184
+ try:
185
+ print(f"Reading Excel file: {excel_file}")
186
+ df = pd.read_excel(excel_file)
187
+ print(f"Excel file loaded. Shape: {df.shape}")
188
+
189
+ # Validate and map columns
190
+ df, column_mapping = validate_and_map_columns(df)
191
+ df = clean_excel_data(df)
192
+
193
+ # Define feature groups with optional fields
194
+ feature_groups = {
195
+ 'core_specs': {
196
+ 'title': 'Core Specifications',
197
+ 'fields': ['Product ID', 'Product Title', 'PLP', 'Bit Size', 'cpu'],
198
+ 'required': ['Product ID', 'Product Title'] # Minimum required fields
199
+ },
200
+ 'memory': {
201
+ 'title': 'Memory',
202
+ 'fields': ['Program Memory (KB)', 'Data Flash (KB)', 'RAM (KB)'],
203
+ 'required': []
204
+ },
205
+ 'communication': {
206
+ 'title': 'Communication Interfaces',
207
+ 'fields': ['Ethernet', 'USB', 'UART', 'SPI', 'I2C', 'CAN', 'LIN'],
208
+ 'required': []
209
+ },
210
+ 'peripherals': {
211
+ 'title': 'Peripherals',
212
+ 'fields': ['Timer', 'ADC', 'DAC', 'RTC', 'DMA'],
213
+ 'required': []
214
+ },
215
+ 'power': {
216
+ 'title': 'Power and Performance',
217
+ 'fields': ['Supply Voltage (V)', 'Operating Freq (Max) (MHz)', 'LVD or PVD'],
218
+ 'required': []
219
+ },
220
+ 'physical': {
221
+ 'title': 'Physical Specifications',
222
+ 'fields': ['Lead Count (#)', 'pkg.Type', 'Temp.Range'],
223
+ 'required': []
224
+ },
225
+ 'interface': {
226
+ 'title': 'Interfaces',
227
+ 'fields': ['I/O Ports', 'Human machine interface'],
228
+ 'required': []
229
+ }
230
+ }
231
+
232
+ # Check for minimum required fields
233
+ required_fields = set()
234
+ for group in feature_groups.values():
235
+ required_fields.update(group['required'])
236
+
237
+ missing_required = [field for field in required_fields if field not in df.columns]
238
+ if missing_required:
239
+ return [], f"Missing essential columns: {', '.join(missing_required)}"
240
+
241
+ documents = []
242
+ for idx, row in df.iterrows():
243
+ content_parts = []
244
+
245
+ for group_name, group_info in feature_groups.items():
246
+ group_content = []
247
+ for field in group_info['fields']:
248
+ if field in df.columns and pd.notna(row.get(field)) and str(row.get(field)).strip() != '':
249
+ value = row[field]
250
+ if isinstance(value, (int, float)):
251
+ if 'KB' in field:
252
+ value = f"{value:g} KB"
253
+ elif 'MHz' in field:
254
+ value = f"{value:g} MHz"
255
+ elif 'V' in field:
256
+ value = f"{value:g}V"
257
+ else:
258
+ value = f"{value:g}"
259
+ group_content.append(f"{field}: {value}")
260
+
261
+ if group_content:
262
+ content_parts.append(f"{group_info['title']}:\n" + "\n".join(group_content))
263
+
264
+ # Create content string
265
+ content = "\n\n".join(content_parts)
266
+
267
+ # Create metadata with available fields
268
+ metadata = {
269
+ "source": "excel",
270
+ "row": idx,
271
+ "product_id": str(row.get('Product ID', '')),
272
+ "product_title": str(row.get('Product Title', '')),
273
+ }
274
+
275
+ # Add optional metadata if available
276
+ optional_metadata = {
277
+ "bit_size": "Bit Size",
278
+ "cpu": "cpu",
279
+ "memory": "Program Memory (KB)",
280
+ "interfaces": ["USB", "Ethernet", "CAN", "SPI", "I2C"]
281
+ }
282
+
283
+ for meta_key, field in optional_metadata.items():
284
+ if isinstance(field, list):
285
+ # Handle interface list
286
+ metadata[meta_key] = [intf for intf in field if intf in df.columns and row.get(intf) == 'Yes']
287
+ elif field in df.columns:
288
+ value = row.get(field)
289
+ if pd.notna(value) and str(value).strip() != '':
290
+ if field == 'Program Memory (KB)':
291
+ metadata[meta_key] = f"{value} KB"
292
+ else:
293
+ metadata[meta_key] = str(value)
294
+
295
+ doc = Document(page_content=content, metadata=metadata)
296
+ documents.append(doc)
297
+
298
+ if not documents:
299
+ return [], "No valid microcontroller data found in Excel file."
300
+
301
+ print(f"Successfully processed {len(documents)} microcontrollers")
302
+ return documents, None
303
+
304
+ except Exception as e:
305
+ import traceback
306
+ print("Excel processing error:")
307
+ print(traceback.format_exc())
308
+ return [], f"Error processing Excel file: {str(e)}"
309
+
310
+ def create_vector_db(documents: List[Document]) -> Optional[FAISS]:
311
+ """Create FAISS vector database with error handling"""
312
+ try:
313
+ text_splitter = RecursiveCharacterTextSplitter(
314
+ chunk_size=2048, # Larger chunk size for complete spec retention
315
+ chunk_overlap=200,
316
+ separators=["\n\n", "\n", ". ", ", ", " "]
317
+ )
318
+
319
+ splits = text_splitter.split_documents(documents)
320
+
321
+ embeddings = HuggingFaceEmbeddings(
322
+ model_name="sentence-transformers/all-mpnet-base-v2"
323
+ )
324
+
325
+ return FAISS.from_documents(splits, embeddings)
326
+
327
+ except Exception as e:
328
+ print(f"Error creating vector database: {str(e)}")
329
+ return None
330
+
331
+ def initialize_llm_chain(vector_db):
332
+ """Initialize LLM chain with enhanced prompting"""
333
+ try:
334
+ llm = HuggingFaceEndpoint(
335
+ repo_id=MODEL_NAME,
336
+ huggingfacehub_api_token=api_token,
337
+ temperature=0.3,
338
+ max_new_tokens=2048,
339
+ top_k=5,
340
+ repetition_penalty=1.1
341
+ )
342
+
343
+ memory = ConversationBufferMemory(
344
+ memory_key="chat_history",
345
+ output_key='answer',
346
+ return_messages=True
347
+ )
348
+
349
+ retriever = vector_db.as_retriever(
350
+ search_type="mmr",
351
+ search_kwargs={
352
+ "k": 5,
353
+ "fetch_k": 8,
354
+ "lambda_mult": 0.7
355
+ }
356
+ )
357
+
358
+ qa_prompt = QA_PROMPT.partial(system_message=SYSTEM_MESSAGE)
359
+
360
+ chain = ConversationalRetrievalChain.from_llm(
361
+ llm=llm,
362
+ retriever=retriever,
363
+ memory=memory,
364
+ return_source_documents=True,
365
+ condense_question_prompt=CONDENSE_QUESTION_PROMPT,
366
+ combine_docs_chain_kwargs={'prompt': qa_prompt}
367
+ )
368
+
369
+ return chain
370
+
371
+ except Exception as e:
372
+ print(f"Error initializing LLM chain: {str(e)}")
373
+ return None
374
+
375
+ def format_mc_response(source_doc: Document) -> str:
376
+ """Format microcontroller source documents for display with robust metadata handling"""
377
+ try:
378
+ if source_doc.metadata.get('source') == 'excel':
379
+ # Get metadata with default values for missing fields
380
+ product_title = source_doc.metadata.get('product_title', 'N/A')
381
+ cpu = source_doc.metadata.get('cpu', 'Not specified')
382
+ memory = source_doc.metadata.get('memory', 'Not specified')
383
+
384
+ formatted_response = (
385
+ f"Product: {product_title}\n"
386
+ f"CPU: {cpu}\n"
387
+ f"Memory: {memory}\n\n"
388
+ f"Specifications:\n{source_doc.page_content}"
389
+ )
390
+ return formatted_response
391
+ return source_doc.page_content
392
+
393
+ except Exception as e:
394
+ # Fallback to returning just the page content if there's any error
395
+ print(f"Error formatting response: {str(e)}")
396
+ return source_doc.page_content
397
+
398
+ def process_query(qa_chain, message: str, history: List) -> Tuple[str, List[str]]:
399
+ """Process user query with enhanced context handling"""
400
+ try:
401
+ # Add requirement analysis to user query
402
+ enhanced_query = f"""Analyze the following microcontroller requirements and provide detailed recommendations:
403
+
404
+ User Requirements: {message}
405
+
406
+ Please consider:
407
+ 1. Core specifications and performance requirements
408
+ 2. Memory requirements and constraints
409
+ 3. Communication interfaces needed
410
+ 4. Peripheral requirements
411
+ 5. Power and operating conditions
412
+ 6. Physical and environmental constraints
413
+
414
+ Provide a detailed comparison of the best matching microcontrollers."""
415
+
416
+ response = qa_chain({
417
+ "question": enhanced_query,
418
+ "chat_history": [(hist[0], hist[1]) for hist in history]
419
+ })
420
+
421
+ sources = response["source_documents"][:3]
422
+ source_contents = [format_mc_response(source) for source in sources]
423
+
424
+ return response["answer"], source_contents
425
+
426
+ except Exception as e:
427
+ return f"Error processing query: {str(e)}", []
428
+
429
+
430
+ def create_interface():
431
+ """Create a Gradio interface with improved horizontal alignment and block sizes."""
432
+ with gr.Blocks(css="""
433
+ #main-title {
434
+ color: #00509e;
435
+ font-family: 'Arial', sans-serif;
436
+ text-align: center;
437
+ margin-bottom: 20px;
438
+ }
439
+ #description {
440
+ color: #333;
441
+ font-family: 'Arial', sans-serif;
442
+ text-align: center;
443
+ margin-bottom: 30px;
444
+ }
445
+ #initialize-btn {
446
+ background-color: #00509e;
447
+ color: white;
448
+ border: none;
449
+ padding: 5px 15px;
450
+ font-size: 14px;
451
+ }
452
+ #initialize-btn:hover {
453
+ background-color: #003f7f;
454
+ }
455
+ .gradio-row {
456
+ margin-bottom: 20px;
457
+ }
458
+ """) as demo:
459
+ # Title and description
460
+ gr.HTML("<h1 id='main-title'>Microcontroller Selection Assistant</h1>")
461
+ gr.HTML("<p id='description'>Select a sample file or upload your database. Then describe your requirements for tailored recommendations.</p>")
462
+
463
+ # File selection section (sample and upload)
464
+ with gr.Row(elem_id="file-section", equal_height=True):
465
+ with gr.Column(scale=1):
466
+ sample_file = gr.Dropdown(
467
+ label="Sample Files",
468
+ choices=["test_data.xlsx"],
469
+ value="test_data.xlsx"
470
+ )
471
+ with gr.Column(scale=1):
472
+ excel_file = gr.File(
473
+ label="Upload Microcontroller Database (Excel)",
474
+ file_types=[".xlsx", ".xls"],
475
+ )
476
+
477
+ # Initialization button and status
478
+ with gr.Row(equal_height=True):
479
+ initialize_btn = gr.Button("Initialize System", elem_id="initialize-btn")
480
+ status = gr.Textbox(label="Status", value="Not initialized", interactive=False)
481
+
482
+ # Chat section
483
+ with gr.Row(equal_height=True):
484
+ chatbot = gr.Chatbot(label="Chat", height=400)
485
+
486
+ # Query input and buttons
487
+ with gr.Row(equal_height=True):
488
+ query = gr.Textbox(
489
+ placeholder="Describe your microcontroller requirements (e.g., '32-bit MCU with USB support and 256KB flash memory')",
490
+ label="Query",
491
+ lines=3
492
+ )
493
+
494
+ with gr.Row(equal_height=True):
495
+ submit_btn = gr.Button("Submit Query")
496
+ clear_btn = gr.Button("Clear Chat")
497
+
498
+ # State handlers
499
+ vector_db_state = gr.State()
500
+ qa_chain_state = gr.State()
501
+
502
+ def init_system(file, sample):
503
+ if not file and not sample:
504
+ return None, None, "Please upload an Excel file or select a sample."
505
+
506
+ file_path = file.name if file else sample
507
+
508
+ docs, error = process_mc_excel(file_path) # Pass Excel file path here
509
+ if error:
510
+ return None, None, error
511
+
512
+ vector_db = create_vector_db(docs)
513
+ if not vector_db:
514
+ return None, None, "Failed to create vector database."
515
+
516
+ qa_chain = initialize_llm_chain(vector_db)
517
+ if not qa_chain:
518
+ return None, None, "Failed to initialize LLM chain."
519
+
520
+ return vector_db, qa_chain, "System initialized successfully!"
521
+
522
+ def handle_query(qa_chain, message, history):
523
+ if qa_chain is None:
524
+ return history + [("Error", "Please initialize the system first.")], ""
525
+
526
+ answer, sources = process_query(qa_chain, message, history)
527
+
528
+ # Include sources in the answer
529
+ if sources:
530
+ answer += "\n\nRelevant Products:\n" + "\n\n".join(sources)
531
+
532
+ return history + [(message, answer)], ""
533
+
534
+ # Button actions
535
+ initialize_btn.click(
536
+ init_system,
537
+ inputs=[excel_file, sample_file],
538
+ outputs=[vector_db_state, qa_chain_state, status]
539
+ )
540
+
541
+ submit_btn.click(
542
+ handle_query,
543
+ inputs=[qa_chain_state, query, chatbot],
544
+ outputs=[chatbot, query]
545
+ )
546
+
547
+ clear_btn.click(
548
+ lambda: ([], ""),
549
+ inputs=[],
550
+ outputs=[chatbot, query]
551
+ )
552
+
553
+ return demo
554
+
555
+ if __name__ == "__main__":
556
+ demo = create_interface()
557
+ demo.launch(debug=True)
requirements.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ torch
2
+ transformers
3
+ sentence-transformers
4
+ langchain==0.3.7
5
+ langchain-community
6
+ tqdm
7
+ accelerate
8
+ pypdf
9
+ faiss-gpu
10
+ ragas
11
+ nltk
12
+ langchain_huggingface
13
+ qdrant-client
14
+ chromadb
test_data.xlsx ADDED
Binary file (14.9 kB). View file