maria355 commited on
Commit
02a3004
Β·
verified Β·
1 Parent(s): 3d18b41

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -389
app.py CHANGED
@@ -109,7 +109,6 @@ def fallback_search(query, country_code=""):
109
  st.error(f"Fallback search failed: {str(e)}")
110
  return []
111
 
112
- # Use LLM to extract relevant information from search results
113
  # Use LLM to extract relevant information from search results
114
  def analyze_search_results(results, query, country):
115
  if not GROQ_API_KEY:
@@ -143,22 +142,23 @@ def analyze_search_results(results, query, country):
143
 
144
  # Call Groq API with mixed model approach (prefer cheaper model)
145
  completion = groq_client.chat.completions.create(
146
- model="llama3-8b-8192",
147
  messages=[{"role": "user", "content": prompt}],
148
- temperature=0.1,
149
- max_tokens=500 # Reduced token limit
150
  )
151
 
152
  try:
153
  # Parse the response as JSON
154
- return json.loads(completion.choices[0].message.content)
 
155
  except json.JSONDecodeError:
156
- # If parsing fails, return empty dict
157
- return {}
158
 
159
  except Exception as e:
160
- st.error(f"Error analyzing search results: {str(e)}")
161
- return {}
162
 
163
  # Try to download PDF
164
  def fetch_pdf(url):
@@ -231,151 +231,19 @@ def find_pdf_in_html_page(url, html_content=None):
231
  return None
232
 
233
  # Display PDF safely with error handling
234
- # Replace your existing display_pdf function with this improved version
235
-
236
  def display_pdf(file_bytesio):
237
- """Display PDF with multiple fallback methods for better browser compatibility"""
238
  try:
239
  file_bytesio.seek(0)
240
- pdf_bytes = file_bytesio.read()
 
 
 
241
 
242
- # Method 1: Try Streamlit's native PDF display (most reliable)
243
- try:
244
- file_bytesio.seek(0)
245
- # Use Streamlit's built-in PDF viewer (works better than iframe)
246
- st.markdown("### πŸ“„ PDF Preview")
247
-
248
- # Try to display using Streamlit's method
249
- # This is more reliable than iframe approach
250
- base64_pdf = base64.b64encode(pdf_bytes).decode('utf-8')
251
-
252
- # Use object tag instead of iframe (better Chrome compatibility)
253
- pdf_display = f'''
254
- <object data="data:application/pdf;base64,{base64_pdf}"
255
- type="application/pdf"
256
- width="100%"
257
- height="800px">
258
- <p>Your browser doesn't support PDF preview.
259
- <a href="data:application/pdf;base64,{base64_pdf}" download="tax_form.pdf">
260
- Click here to download the PDF</a>
261
- </p>
262
- </object>
263
- '''
264
-
265
- st.markdown(pdf_display, unsafe_allow_html=True)
266
-
267
- except Exception as e:
268
- # Method 2: Fallback to download only
269
- st.warning("⚠️ PDF preview not available in your browser. Please download to view.")
270
- st.download_button(
271
- label="πŸ“₯ Download PDF to View",
272
- data=pdf_bytes,
273
- file_name="tax_form.pdf",
274
- mime="application/pdf",
275
- use_container_width=True
276
- )
277
-
278
- # Method 3: Try to extract first page as image (optional)
279
- try:
280
- # Convert first page to image for preview
281
- import fitz # PyMuPDF
282
- file_bytesio.seek(0)
283
- doc = fitz.open(stream=file_bytesio, filetype="pdf")
284
-
285
- if len(doc) > 0:
286
- page = doc[0]
287
- pix = page.get_pixmap(matrix=fitz.Matrix(1.5, 1.5)) # 1.5x zoom
288
- img_data = pix.tobytes("png")
289
-
290
- st.markdown("### πŸ“„ First Page Preview")
291
- st.image(img_data, caption="First page of the tax form", use_container_width=True)
292
-
293
- if len(doc) > 1:
294
- st.info(f"This form has {len(doc)} pages total. Download the PDF to see all pages.")
295
-
296
- doc.close()
297
-
298
- except Exception as img_error:
299
- st.info("PDF loaded successfully! Use the download button above to view the complete form.")
300
-
301
- except Exception as e:
302
- st.error(f"Error loading PDF: {str(e)}")
303
- st.info("Please try uploading the PDF again or use a different file.")
304
-
305
- # Alternative function for better Streamlit compatibility
306
- def display_pdf_streamlit_native(file_bytesio):
307
- """Use Streamlit's native PDF handling"""
308
- try:
309
  file_bytesio.seek(0)
310
-
311
- # Simply use st.download_button which always works
312
- st.download_button(
313
- label="πŸ“₯ Download PDF to View",
314
- data=file_bytesio,
315
- file_name="tax_form.pdf",
316
- mime="application/pdf",
317
- use_container_width=True
318
- )
319
-
320
- # Try to show first page as image
321
- try:
322
- import fitz
323
- file_bytesio.seek(0)
324
- doc = fitz.open(stream=file_bytesio, filetype="pdf")
325
-
326
- if len(doc) > 0:
327
- # Show first page as image
328
- page = doc[0]
329
- pix = page.get_pixmap(matrix=fitz.Matrix(2, 2)) # 2x zoom for better quality
330
- img_data = pix.tobytes("png")
331
-
332
- st.image(img_data, caption=f"Preview: Page 1 of {len(doc)}", use_column_width=True)
333
-
334
- if len(doc) > 1:
335
- st.info(f"πŸ“„ This form has {len(doc)} pages. Download the PDF to see all pages.")
336
-
337
- doc.close()
338
-
339
- except Exception:
340
- st.info("PDF ready for download. Click the button above to view the complete form.")
341
-
342
- except Exception as e:
343
- st.error(f"Error processing PDF: {str(e)}")
344
-
345
- # Even simpler fallback function
346
- def display_pdf_simple(file_bytesio):
347
- """Simple PDF display with download only"""
348
- try:
349
- file_bytesio.seek(0)
350
- pdf_bytes = file_bytesio.read()
351
-
352
- st.markdown("### πŸ“„ Tax Form Ready")
353
- st.success("βœ… PDF loaded successfully!")
354
-
355
- # Provide download button
356
- st.download_button(
357
- label="πŸ“₯ Download PDF to View",
358
- data=pdf_bytes,
359
- file_name="pakistan_tax_form.pdf",
360
- mime="application/pdf",
361
- use_container_width=True
362
- )
363
-
364
- # Show PDF info
365
- try:
366
- import fitz
367
- file_bytesio.seek(0)
368
- doc = fitz.open(stream=file_bytesio, filetype="pdf")
369
- page_count = len(doc)
370
- doc.close()
371
-
372
- st.info(f"πŸ“„ Form contains {page_count} page(s)")
373
-
374
- except Exception:
375
- st.info("πŸ“„ PDF is ready for download")
376
-
377
  except Exception as e:
378
- st.error(f"Error: {str(e)}")
 
379
 
380
 
381
  # Extract interactive fields from PDF
@@ -410,32 +278,38 @@ def extract_form_fields(file_bytesio):
410
  except Exception as e:
411
  st.error(f"Error extracting form fields: {str(e)}")
412
  return []
 
413
  # Use LLM to explain form fields
414
  def explain_form_fields(fields, country, form_name):
415
  if not GROQ_API_KEY or not fields:
416
  return {}
417
 
418
  try:
419
- # CHANGE: Limit fields and reduce content
420
- limited_fields = fields[:10] # Only take first 10 fields
421
- fields_summary = []
422
- for field in limited_fields:
423
- fields_summary.append({
424
- "name": field.get("name", "Unknown"),
425
- "type": field.get("type", "Unknown")
426
- })
427
-
428
- fields_json = json.dumps(fields_summary, indent=1) # Less indentation
429
 
430
  prompt = f"""
431
- Tax form ({form_name}) from {country} has these fields:
432
  {fields_json}
433
 
434
- Provide brief explanations for these field types in JSON format:
 
 
 
 
 
435
  {{
436
- "field_explanations": {{
437
- "field_name": "brief explanation"
438
- }}
 
 
 
 
 
 
 
 
 
439
  }}
440
  """
441
 
@@ -443,19 +317,19 @@ def explain_form_fields(fields, country, form_name):
443
  model="llama3-8b-8192",
444
  messages=[{"role": "user", "content": prompt}],
445
  temperature=0.1,
446
- max_tokens=500 # Reduced token limit
447
  )
448
 
449
  try:
450
- # Parse the response as JSON
451
- return json.loads(completion.choices[0].message.content)
452
  except json.JSONDecodeError:
453
- # If parsing fails, return empty dict
454
  return {}
455
 
456
  except Exception as e:
457
  st.error(f"Error explaining form fields: {str(e)}")
458
  return {}
 
459
  # Fill PDF form with user data
460
  def fill_pdf_form(file_bytesio, field_values):
461
  try:
@@ -627,97 +501,6 @@ def recommend_tax_form_type(user_query):
627
 
628
  except Exception as e:
629
  return ["Income Tax Return", "Sales Tax Return", "Withholding Tax Statement"]
630
- # Generate summary of uploaded form
631
- def generate_form_summary(form_fields, file_name):
632
- """Generate a summary of the uploaded tax form using LLM"""
633
- if not GROQ_API_KEY or not form_fields:
634
- return None
635
-
636
- try:
637
- # Prepare form fields information
638
- fields_info = []
639
- for field in form_fields[:20]: # Limit to first 20 fields to avoid token limits
640
- fields_info.append({
641
- "name": field.get("name", ""),
642
- "type": field.get("type", ""),
643
- "page": field.get("page", 1)
644
- })
645
-
646
- fields_json = json.dumps(fields_info, indent=2)
647
-
648
- prompt = f"""
649
- Analyze this Pakistani tax form: "{file_name}"
650
-
651
- Form fields found:
652
- {fields_json}
653
-
654
- Please provide a summary that includes:
655
- 1. What type of tax form this appears to be
656
- 2. Who should use this form (individuals, businesses, etc.)
657
- 3. Main sections/categories of information required
658
- 4. Key requirements or important notes
659
-
660
- Keep the summary concise but informative, focused on Pakistani tax context.
661
- """
662
-
663
- completion = groq_client.chat.completions.create(
664
- model="llama3-8b-8192",
665
- messages=[{"role": "user", "content": prompt}],
666
- temperature=0.2,
667
- max_tokens=600
668
- )
669
-
670
- return completion.choices[0].message.content
671
-
672
- except Exception as e:
673
- st.error(f"Error generating summary: {str(e)}")
674
- return None
675
-
676
- # Generate response for uploaded form questions
677
- def generate_upload_form_response(question, file_name, form_fields):
678
- """Generate responses to questions about uploaded forms"""
679
- if not GROQ_API_KEY:
680
- return "I need an LLM API key to analyze and answer questions about your uploaded form."
681
-
682
- try:
683
- # Prepare context from form fields
684
- context = f"User uploaded a tax form: '{file_name}'\n"
685
-
686
- if form_fields:
687
- # Get field names and types for context
688
- field_info = []
689
- for field in form_fields[:15]: # Limit for token efficiency
690
- field_info.append(f"{field.get('name', 'Unknown')} ({field.get('type', 'Unknown')})")
691
-
692
- context += f"Form contains fields: {', '.join(field_info)}\n"
693
-
694
- context += f"User question: {question}\n"
695
-
696
- prompt = f"""
697
- {context}
698
-
699
- As a Pakistani tax expert, answer the user's question about their uploaded form.
700
-
701
- Provide helpful guidance that:
702
- 1. Addresses their specific question
703
- 2. Relates to Pakistani tax requirements
704
- 3. Explains any technical terms simply
705
- 4. Suggests next steps if relevant
706
-
707
- Be conversational and helpful.
708
- """
709
-
710
- completion = groq_client.chat.completions.create(
711
- model="llama3-8b-8192",
712
- messages=[{"role": "user", "content": prompt}],
713
- temperature=0.3,
714
- max_tokens=700
715
- )
716
-
717
- return completion.choices[0].message.content
718
-
719
- except Exception as e:
720
- return f"I encountered an error while analyzing your form: {str(e)}"
721
  # Main Streamlit app
722
  def main():
723
  st.set_page_config(
@@ -994,148 +777,63 @@ def main():
994
 
995
  # If form has fields, show them
996
  if 'form_fields' in st.session_state and st.session_state.form_fields:
997
- st.markdown("### πŸ“ Form Fields Found")
998
 
999
- # Simple field listing
1000
- field_count = len(st.session_state.form_fields)
1001
- st.info(f"Found {field_count} fillable fields in this form")
 
 
 
 
 
 
 
 
1002
 
1003
- # Group fields by type
1004
- field_types = {}
1005
- for field in st.session_state.form_fields:
1006
- field_type = field.get('type', 'Unknown')
1007
- if field_type not in field_types:
1008
- field_types[field_type] = []
1009
- field_types[field_type].append(field.get('name', 'Unnamed'))
 
 
 
 
 
 
 
 
 
 
 
 
1010
 
1011
- # Display field types and count
1012
- for field_type, field_names in field_types.items():
1013
- with st.expander(f"{field_type} Fields ({len(field_names)})"):
1014
- for name in field_names:
1015
- st.write(f"β€’ {name}")
1016
  else:
1017
  st.warning("⚠️ This form doesn't have fillable fields. It may be a scanned document or not an interactive form.")
1018
  st.info("You can still view and download the form, but automatic filling isn't available.")
1019
-
1020
- # Download form
1021
- st.download_button(
1022
- label="πŸ“₯ Download Form",
1023
- data=st.session_state.pdf_bytes,
1024
- file_name="pakistan_tax_form.pdf",
1025
- mime="application/pdf"
1026
- )
1027
-
1028
- # Add a question and answer section for this form
1029
- st.markdown("### ❓ Questions about this form?")
1030
- form_question = st.text_input("Ask a question about this form:", key="form_question_input")
1031
-
1032
- if form_question:
1033
- with st.spinner("Getting answer..."):
1034
- form_response = tax_agent_response(form_question, tax_form_type=form_type)
1035
- st.markdown(form_response)
1036
- # Tab 3: Upload Form
1037
- with tab3:
1038
- st.header("Upload Your Tax Form")
1039
- st.markdown("Upload a PDF tax form to analyze, get summaries, and ask questions about it.")
1040
-
1041
- # File uploader
1042
- uploaded_file = st.file_uploader(
1043
- "Choose a PDF file",
1044
- type=['pdf'],
1045
- help="Upload any Pakistani tax form PDF for analysis"
1046
- )
1047
-
1048
- if uploaded_file is not None:
1049
- # Store uploaded file in session state
1050
- st.session_state.pdf_bytes = BytesIO(uploaded_file.read())
1051
- st.session_state.uploaded_file_name = uploaded_file.name
1052
-
1053
- # Display success message
1054
- st.success(f"βœ… Successfully uploaded: {uploaded_file.name}")
1055
-
1056
- # Extract form fields from uploaded PDF
1057
- with st.spinner("Analyzing uploaded form..."):
1058
- st.session_state.form_fields = extract_form_fields(st.session_state.pdf_bytes)
1059
-
1060
- # Display PDF preview
1061
- st.markdown("### πŸ“„ Form Preview")
1062
- display_pdf(st.session_state.pdf_bytes)
1063
-
1064
- # Generate summary using LLM
1065
- if GROQ_API_KEY:
1066
- with st.spinner("Generating form summary..."):
1067
- summary = generate_form_summary(st.session_state.form_fields, uploaded_file.name)
1068
- if summary:
1069
- st.markdown("### πŸ“‹ Form Summary")
1070
- st.markdown(summary)
1071
- # Show form fields if available
1072
- if st.session_state.form_fields:
1073
- st.markdown("### πŸ“ Form Fields Found")
1074
-
1075
- # Simple field listing
1076
- field_count = len(st.session_state.form_fields)
1077
- st.info(f"Found {field_count} fillable fields in this form")
1078
 
1079
- # Group fields by type
1080
- field_types = {}
1081
- for field in st.session_state.form_fields:
1082
- field_type = field.get('type', 'Unknown')
1083
- if field_type not in field_types:
1084
- field_types[field_type] = []
1085
- field_types[field_type].append(field.get('name', 'Unnamed'))
1086
-
1087
- # Display field types and count
1088
- for field_type, field_names in field_types.items():
1089
- with st.expander(f"{field_type} Fields ({len(field_names)})"):
1090
- for name in field_names:
1091
- st.write(f"β€’ {name}")
1092
- else:
1093
- st.warning("⚠️ This form doesn't have fillable fields or couldn't be analyzed.")
1094
-
1095
- # Q&A Section for uploaded form
1096
- st.markdown("### ❓ Ask Questions About This Form")
1097
- st.markdown("Get help understanding your uploaded tax form.")
1098
-
1099
- upload_question = st.text_input(
1100
- "Ask a question about this form:",
1101
- placeholder="What is this form used for? How do I fill section X?",
1102
- key="upload_question_input"
1103
- )
1104
-
1105
- if upload_question:
1106
- with st.spinner("Analyzing your question..."):
1107
- # Generate response using the uploaded form context
1108
- upload_response = generate_upload_form_response(
1109
- upload_question,
1110
- uploaded_file.name,
1111
- st.session_state.form_fields
1112
- )
1113
-
1114
- st.markdown("### πŸ’¬ Response:")
1115
- st.markdown(upload_response)
1116
-
1117
- # Download options
1118
- st.markdown("### πŸ“₯ Download Options")
1119
- col1, col2 = st.columns(2)
1120
-
1121
- with col1:
1122
- # Download original form
1123
  st.download_button(
1124
- label="πŸ“₯ Download Original Form",
1125
  data=st.session_state.pdf_bytes,
1126
- file_name=uploaded_file.name,
1127
  mime="application/pdf"
1128
  )
1129
-
1130
- else:
1131
- st.info("πŸ‘† Please upload a PDF tax form to get started.")
1132
- st.markdown("""
1133
- **What you can do with uploaded forms:**
1134
- - πŸ“„ View and preview the form
1135
- - πŸ“‹ Get AI-generated summaries
1136
- - πŸ” Analyze form fields and sections
1137
- - ❓ Ask questions about the form
1138
- """)
1139
 
1140
  if __name__ == "__main__":
1141
  main()
 
 
109
  st.error(f"Fallback search failed: {str(e)}")
110
  return []
111
 
 
112
  # Use LLM to extract relevant information from search results
113
  def analyze_search_results(results, query, country):
114
  if not GROQ_API_KEY:
 
142
 
143
  # Call Groq API with mixed model approach (prefer cheaper model)
144
  completion = groq_client.chat.completions.create(
145
+ model="llama3-8b-8192", # Free/cheaper model
146
  messages=[{"role": "user", "content": prompt}],
147
+ temperature=0.0,
148
+ max_tokens=800
149
  )
150
 
151
  try:
152
  # Parse the response as JSON
153
+ analysis = json.loads(completion.choices[0].message.content)
154
+ return results, analysis
155
  except json.JSONDecodeError:
156
+ # If parsing fails, return the original results
157
+ return results, None
158
 
159
  except Exception as e:
160
+ st.error(f"LLM analysis failed: {str(e)}")
161
+ return results, None
162
 
163
  # Try to download PDF
164
  def fetch_pdf(url):
 
231
  return None
232
 
233
  # Display PDF safely with error handling
 
 
234
  def display_pdf(file_bytesio):
 
235
  try:
236
  file_bytesio.seek(0)
237
+ base64_pdf = base64.b64encode(file_bytesio.read()).decode('utf-8')
238
+ pdf_display = f'<iframe src="data:application/pdf;base64,{base64_pdf}" width="100%" height="800" type="application/pdf"></iframe>'
239
+ st.markdown(pdf_display, unsafe_allow_html=True)
240
+ st.success("PDF loaded successfully!")
241
 
242
+ # Add a direct download option for better user experience
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
  file_bytesio.seek(0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  except Exception as e:
245
+ st.error(f"Error displaying PDF: {str(e)}")
246
+ st.info("If the PDF isn't displaying, you can try using the direct link.")
247
 
248
 
249
  # Extract interactive fields from PDF
 
278
  except Exception as e:
279
  st.error(f"Error extracting form fields: {str(e)}")
280
  return []
281
+
282
  # Use LLM to explain form fields
283
  def explain_form_fields(fields, country, form_name):
284
  if not GROQ_API_KEY or not fields:
285
  return {}
286
 
287
  try:
288
+ fields_json = json.dumps(fields, indent=2)
 
 
 
 
 
 
 
 
 
289
 
290
  prompt = f"""
291
+ These are form fields from a tax form ({form_name}) from {country}:
292
  {fields_json}
293
 
294
+ Please analyze these fields and:
295
+ 1. Group them into logical sections (personal info, income, deductions, etc.)
296
+ 2. Explain any technical tax terms in simple language
297
+ 3. Identify which fields are mandatory vs. optional if possible
298
+
299
+ Format your response as JSON with the following structure:
300
  {{
301
+ "sections": [
302
+ {{
303
+ "name": "section name",
304
+ "fields": ["field1", "field2"],
305
+ "explanation": "explanation of this section"
306
+ }}
307
+ ],
308
+ "key_terms": {{
309
+ "term1": "simple explanation",
310
+ "term2": "simple explanation"
311
+ }},
312
+ "mandatory_fields": ["field1", "field2"]
313
  }}
314
  """
315
 
 
317
  model="llama3-8b-8192",
318
  messages=[{"role": "user", "content": prompt}],
319
  temperature=0.1,
320
+ max_tokens=1000
321
  )
322
 
323
  try:
324
+ explanation = json.loads(completion.choices[0].message.content)
325
+ return explanation
326
  except json.JSONDecodeError:
 
327
  return {}
328
 
329
  except Exception as e:
330
  st.error(f"Error explaining form fields: {str(e)}")
331
  return {}
332
+
333
  # Fill PDF form with user data
334
  def fill_pdf_form(file_bytesio, field_values):
335
  try:
 
501
 
502
  except Exception as e:
503
  return ["Income Tax Return", "Sales Tax Return", "Withholding Tax Statement"]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
  # Main Streamlit app
505
  def main():
506
  st.set_page_config(
 
777
 
778
  # If form has fields, show them
779
  if 'form_fields' in st.session_state and st.session_state.form_fields:
780
+ st.markdown("### πŸ“ Form Fields")
781
 
782
+ # Get field explanations if LLM is available
783
+ field_explanations = {}
784
+ if GROQ_API_KEY:
785
+ with st.spinner("Analyzing form fields..."):
786
+ explanations = explain_form_fields(
787
+ st.session_state.form_fields,
788
+ "Pakistan",
789
+ f"{form_type} form"
790
+ )
791
+ if explanations:
792
+ field_explanations = explanations
793
 
794
+ # Display fields with explanations if available
795
+ if field_explanations and "sections" in field_explanations:
796
+ for section in field_explanations["sections"]:
797
+ with st.expander(f"πŸ“‘ {section['name']}"):
798
+ st.write(section["explanation"])
799
+ for field_name in section["fields"]:
800
+ matching_fields = [f for f in st.session_state.form_fields
801
+ if f["name"] == field_name]
802
+ if matching_fields:
803
+ field = matching_fields[0]
804
+ st.write(f"**{field['name']}** ({field['type']})")
805
+ else:
806
+ # Simple field display without explanations
807
+ for field in st.session_state.form_fields:
808
+ st.write(f"**{field['name']}** ({field['type']})")
809
+
810
+ # Option to fill form
811
+ st.markdown("### ✏️ Fill This Form")
812
+ st.info("This feature will help you fill in the form fields.")
813
 
814
+ if st.button("Start Filling Form"):
815
+ st.session_state.is_filling = True
 
 
 
816
  else:
817
  st.warning("⚠️ This form doesn't have fillable fields. It may be a scanned document or not an interactive form.")
818
  st.info("You can still view and download the form, but automatic filling isn't available.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
819
 
820
+ # Option to download the non-fillable form
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
821
  st.download_button(
822
+ label="πŸ“₯ Download Form",
823
  data=st.session_state.pdf_bytes,
824
+ file_name="pakistan_tax_form.pdf",
825
  mime="application/pdf"
826
  )
827
+
828
+ # Add a question and answer section for this form
829
+ st.markdown("### ❓ Questions about this form?")
830
+ form_question = st.text_input("Ask a question about this form:", key="form_question_input")
831
+
832
+ if form_question:
833
+ with st.spinner("Getting answer..."):
834
+ form_response = tax_agent_response(form_question, tax_form_type=form_type)
835
+ st.markdown(form_response)
 
836
 
837
  if __name__ == "__main__":
838
  main()
839
+