DocUA commited on
Commit
df84c2c
Β·
1 Parent(s): 74541bd

feat: Enhance conversation verification UI with new buttons and error handling

Browse files
src/interface/conversation_verification_ui.py CHANGED
@@ -123,6 +123,10 @@ class VerificationInterface:
123
  gr.Markdown("### Quick Actions")
124
  mark_all_correct_btn = gr.Button("βœ… Mark All Remaining as Correct", size="sm")
125
 
 
 
 
 
126
  # Export section
127
  gr.Markdown("### Export Results")
128
  export_btn = gr.Button("πŸ“Š Export to CSV", variant="primary")
@@ -180,6 +184,18 @@ class VerificationInterface:
180
  outputs=[exchange_display, current_position, stats_display, progress_bar]
181
  )
182
 
 
 
 
 
 
 
 
 
 
 
 
 
183
  export_btn.click(
184
  fn=self._export_results,
185
  inputs=[session_state],
@@ -319,38 +335,57 @@ class VerificationInterface:
319
 
320
  def _handle_correct_feedback(self, session: VerificationSession, index: int) -> Tuple[str, str, str, str, int]:
321
  """Handle correct classification feedback."""
322
- if index >= len(session.verification_records):
323
- return "No more exchanges", f"Exchange {index + 1} of {len(session.verification_records)}", "", "", index
324
-
325
- record = session.verification_records[index]
326
-
327
- # Submit feedback
328
- feedback = VerificationFeedback(
329
- exchange_id=record.exchange_id,
330
- is_correct=True
331
- )
332
-
333
- self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback)
334
-
335
- # Reload session to get updated data
336
- updated_session = self.manager.load_session(session.session_id)
337
-
338
- # Move to next unverified exchange
339
- next_index = self._find_next_unverified_index(updated_session, index)
340
-
341
- if next_index is not None:
342
- next_record = updated_session.verification_records[next_index]
343
- exchange_html = self._render_exchange_review(next_record)
344
- position_html = f"Exchange {next_index + 1} of {len(updated_session.verification_records)}"
345
- else:
346
- exchange_html = "<div style='text-align: center; padding: 2em;'><h3>πŸŽ‰ All exchanges verified!</h3><p>You can now export the results.</p></div>"
347
- position_html = "Verification Complete"
348
- next_index = index
349
-
350
- stats_html = self._render_statistics(updated_session)
351
- progress_html = self._render_progress_bar(updated_session)
352
-
353
- return exchange_html, position_html, stats_html, progress_html, next_index
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
 
355
  def _handle_incorrect_feedback(
356
  self,
@@ -361,41 +396,67 @@ class VerificationInterface:
361
  notes: str
362
  ) -> Tuple[str, str, str, str, int, gr.Column]:
363
  """Handle incorrect classification feedback."""
364
- if index >= len(session.verification_records):
365
- return "No more exchanges", f"Exchange {index + 1} of {len(session.verification_records)}", "", "", index, gr.Column(visible=False)
366
-
367
- record = session.verification_records[index]
368
-
369
- # Submit feedback
370
- feedback = VerificationFeedback(
371
- exchange_id=record.exchange_id,
372
- is_correct=False,
373
- correct_classification=correct_classification,
374
- correction_reason=correction_reason,
375
- notes=notes if notes.strip() else None
376
- )
377
-
378
- self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback)
379
-
380
- # Reload session
381
- updated_session = self.manager.load_session(session.session_id)
382
-
383
- # Move to next unverified exchange
384
- next_index = self._find_next_unverified_index(updated_session, index)
385
-
386
- if next_index is not None:
387
- next_record = updated_session.verification_records[next_index]
388
- exchange_html = self._render_exchange_review(next_record)
389
- position_html = f"Exchange {next_index + 1} of {len(updated_session.verification_records)}"
390
- else:
391
- exchange_html = "<div style='text-align: center; padding: 2em;'><h3>πŸŽ‰ All exchanges verified!</h3><p>You can now export the results.</p></div>"
392
- position_html = "Verification Complete"
393
- next_index = index
394
-
395
- stats_html = self._render_statistics(updated_session)
396
- progress_html = self._render_progress_bar(updated_session)
397
-
398
- return exchange_html, position_html, stats_html, progress_html, next_index, gr.Column(visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
 
400
  def _navigate_previous(self, session: VerificationSession, index: int) -> Tuple[str, str, int]:
401
  """Navigate to previous exchange."""
@@ -417,44 +478,95 @@ class VerificationInterface:
417
 
418
  def _mark_all_remaining_correct(self, session: VerificationSession, current_index: int) -> Tuple[str, str, str, str]:
419
  """Mark all remaining unverified exchanges as correct."""
420
- unverified_records = session.get_unverified_records()
421
-
422
- for record in unverified_records:
423
- feedback = VerificationFeedback(
424
- exchange_id=record.exchange_id,
425
- is_correct=True
426
- )
427
- self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback)
428
-
429
- # Reload session
430
- updated_session = self.manager.load_session(session.session_id)
431
-
432
- exchange_html = "<div style='text-align: center; padding: 2em;'><h3>πŸŽ‰ All exchanges verified!</h3><p>All remaining exchanges marked as correct.</p></div>"
433
- position_html = "Verification Complete"
434
- stats_html = self._render_statistics(updated_session)
435
- progress_html = self._render_progress_bar(updated_session)
436
-
437
- return exchange_html, position_html, stats_html, progress_html
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
 
439
  def _export_results(self, session: VerificationSession) -> str:
440
  """Export verification results to CSV."""
441
  try:
 
 
 
 
 
 
 
 
 
 
442
  from src.core.verification_exporter import VerificationExporter
443
  exporter = VerificationExporter()
444
  csv_path = exporter.export_session_to_csv(session)
445
 
 
 
 
 
 
446
  return f"""
447
  <div style="background-color: #d4edda; padding: 1em; border-radius: 4px;">
448
  <strong>βœ… Export Successful!</strong><br>
449
- File saved: <code>{csv_path}</code><br>
450
- <small>Check your downloads folder</small>
 
 
451
  </div>
452
  """
453
  except Exception as e:
 
 
 
454
  return f"""
455
  <div style="background-color: #f8d7da; padding: 1em; border-radius: 4px;">
456
  <strong>❌ Export Failed</strong><br>
457
- Error: {str(e)}
 
458
  </div>
459
  """
460
 
@@ -469,4 +581,96 @@ class VerificationInterface:
469
  if session.verification_records[i].is_correct is None:
470
  return i
471
 
472
- return None # All verified
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  gr.Markdown("### Quick Actions")
124
  mark_all_correct_btn = gr.Button("βœ… Mark All Remaining as Correct", size="sm")
125
 
126
+ with gr.Row():
127
+ mark_green_correct_btn = gr.Button("🟒 All GREEN Correct", size="sm", scale=1)
128
+ skip_to_errors_btn = gr.Button("πŸ” Skip to Errors", size="sm", scale=1)
129
+
130
  # Export section
131
  gr.Markdown("### Export Results")
132
  export_btn = gr.Button("πŸ“Š Export to CSV", variant="primary")
 
184
  outputs=[exchange_display, current_position, stats_display, progress_bar]
185
  )
186
 
187
+ mark_green_correct_btn.click(
188
+ fn=self._mark_all_green_correct,
189
+ inputs=[session_state],
190
+ outputs=[exchange_display, current_position, stats_display, progress_bar, current_index]
191
+ )
192
+
193
+ skip_to_errors_btn.click(
194
+ fn=self._skip_to_next_error,
195
+ inputs=[session_state, current_index],
196
+ outputs=[exchange_display, current_position, current_index]
197
+ )
198
+
199
  export_btn.click(
200
  fn=self._export_results,
201
  inputs=[session_state],
 
335
 
336
  def _handle_correct_feedback(self, session: VerificationSession, index: int) -> Tuple[str, str, str, str, int]:
337
  """Handle correct classification feedback."""
338
+ try:
339
+ if index >= len(session.verification_records):
340
+ return "No more exchanges", f"Exchange {index + 1} of {len(session.verification_records)}", "", "", index
341
+
342
+ record = session.verification_records[index]
343
+
344
+ # Submit feedback
345
+ feedback = VerificationFeedback(
346
+ exchange_id=record.exchange_id,
347
+ is_correct=True
348
+ )
349
+
350
+ success = self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback)
351
+ if not success:
352
+ return "❌ Failed to submit feedback", f"Exchange {index + 1} of {len(session.verification_records)}", "", "", index
353
+
354
+ # Reload session to get updated data
355
+ updated_session = self.manager.load_session(session.session_id)
356
+ if not updated_session:
357
+ return "❌ Failed to reload session", f"Exchange {index + 1} of {len(session.verification_records)}", "", "", index
358
+
359
+ # Update current session reference
360
+ self.current_session = updated_session
361
+
362
+ # Move to next unverified exchange
363
+ next_index = self._find_next_unverified_index(updated_session, index)
364
+
365
+ if next_index is not None:
366
+ next_record = updated_session.verification_records[next_index]
367
+ exchange_html = self._render_exchange_review(next_record)
368
+ position_html = f"Exchange {next_index + 1} of {len(updated_session.verification_records)}"
369
+ else:
370
+ exchange_html = """
371
+ <div style='text-align: center; padding: 2em; background-color: #d4edda; border-radius: 8px;'>
372
+ <h3>πŸŽ‰ All exchanges verified!</h3>
373
+ <p>Great job! You can now export the results using the Export button below.</p>
374
+ </div>
375
+ """
376
+ position_html = "Verification Complete"
377
+ next_index = index
378
+
379
+ stats_html = self._render_statistics(updated_session)
380
+ progress_html = self._render_progress_bar(updated_session)
381
+
382
+ return exchange_html, position_html, stats_html, progress_html, next_index
383
+
384
+ except Exception as e:
385
+ print(f"Error in _handle_correct_feedback: {e}")
386
+ import traceback
387
+ traceback.print_exc()
388
+ return f"❌ Error: {str(e)}", f"Exchange {index + 1}", "", "", index
389
 
390
  def _handle_incorrect_feedback(
391
  self,
 
396
  notes: str
397
  ) -> Tuple[str, str, str, str, int, gr.Column]:
398
  """Handle incorrect classification feedback."""
399
+ try:
400
+ if index >= len(session.verification_records):
401
+ return "No more exchanges", f"Exchange {index + 1} of {len(session.verification_records)}", "", "", index, gr.Column(visible=False)
402
+
403
+ # Validate inputs
404
+ if not correct_classification:
405
+ return "❌ Please select correct classification", f"Exchange {index + 1}", "", "", index, gr.Column(visible=True)
406
+
407
+ if not correction_reason:
408
+ return "❌ Please select correction reason", f"Exchange {index + 1}", "", "", index, gr.Column(visible=True)
409
+
410
+ record = session.verification_records[index]
411
+
412
+ # Submit feedback
413
+ feedback = VerificationFeedback(
414
+ exchange_id=record.exchange_id,
415
+ is_correct=False,
416
+ correct_classification=correct_classification,
417
+ correction_reason=correction_reason,
418
+ notes=notes.strip() if notes and notes.strip() else None
419
+ )
420
+
421
+ success = self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback)
422
+ if not success:
423
+ return "❌ Failed to submit correction", f"Exchange {index + 1}", "", "", index, gr.Column(visible=True)
424
+
425
+ # Reload session
426
+ updated_session = self.manager.load_session(session.session_id)
427
+ if not updated_session:
428
+ return "❌ Failed to reload session", f"Exchange {index + 1}", "", "", index, gr.Column(visible=True)
429
+
430
+ # Update current session reference
431
+ self.current_session = updated_session
432
+
433
+ # Move to next unverified exchange
434
+ next_index = self._find_next_unverified_index(updated_session, index)
435
+
436
+ if next_index is not None:
437
+ next_record = updated_session.verification_records[next_index]
438
+ exchange_html = self._render_exchange_review(next_record)
439
+ position_html = f"Exchange {next_index + 1} of {len(updated_session.verification_records)}"
440
+ else:
441
+ exchange_html = """
442
+ <div style='text-align: center; padding: 2em; background-color: #d4edda; border-radius: 8px;'>
443
+ <h3>πŸŽ‰ All exchanges verified!</h3>
444
+ <p>Great job! You can now export the results using the Export button below.</p>
445
+ </div>
446
+ """
447
+ position_html = "Verification Complete"
448
+ next_index = index
449
+
450
+ stats_html = self._render_statistics(updated_session)
451
+ progress_html = self._render_progress_bar(updated_session)
452
+
453
+ return exchange_html, position_html, stats_html, progress_html, next_index, gr.Column(visible=False)
454
+
455
+ except Exception as e:
456
+ print(f"Error in _handle_incorrect_feedback: {e}")
457
+ import traceback
458
+ traceback.print_exc()
459
+ return f"❌ Error: {str(e)}", f"Exchange {index + 1}", "", "", index, gr.Column(visible=True)
460
 
461
  def _navigate_previous(self, session: VerificationSession, index: int) -> Tuple[str, str, int]:
462
  """Navigate to previous exchange."""
 
478
 
479
  def _mark_all_remaining_correct(self, session: VerificationSession, current_index: int) -> Tuple[str, str, str, str]:
480
  """Mark all remaining unverified exchanges as correct."""
481
+ try:
482
+ unverified_records = session.get_unverified_records()
483
+
484
+ if not unverified_records:
485
+ return """
486
+ <div style='text-align: center; padding: 2em; background-color: #fff3cd; border-radius: 8px;'>
487
+ <h3>⚠️ No unverified exchanges</h3>
488
+ <p>All exchanges have already been verified.</p>
489
+ </div>
490
+ """, "All Verified", "", ""
491
+
492
+ print(f"πŸ”„ Marking {len(unverified_records)} remaining exchanges as correct...")
493
+
494
+ success_count = 0
495
+ for record in unverified_records:
496
+ feedback = VerificationFeedback(
497
+ exchange_id=record.exchange_id,
498
+ is_correct=True
499
+ )
500
+ if self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback):
501
+ success_count += 1
502
+
503
+ # Reload session
504
+ updated_session = self.manager.load_session(session.session_id)
505
+ if not updated_session:
506
+ return "❌ Failed to reload session", "Error", "", ""
507
+
508
+ # Update current session reference
509
+ self.current_session = updated_session
510
+
511
+ exchange_html = f"""
512
+ <div style='text-align: center; padding: 2em; background-color: #d4edda; border-radius: 8px;'>
513
+ <h3>πŸŽ‰ Batch verification complete!</h3>
514
+ <p>Marked <strong>{success_count}</strong> exchanges as correct.</p>
515
+ <p>You can now export the results using the Export button below.</p>
516
+ </div>
517
+ """
518
+ position_html = "Verification Complete"
519
+ stats_html = self._render_statistics(updated_session)
520
+ progress_html = self._render_progress_bar(updated_session)
521
+
522
+ return exchange_html, position_html, stats_html, progress_html
523
+
524
+ except Exception as e:
525
+ print(f"Error in batch verification: {e}")
526
+ import traceback
527
+ traceback.print_exc()
528
+ return f"❌ Batch verification error: {str(e)}", "Error", "", ""
529
 
530
  def _export_results(self, session: VerificationSession) -> str:
531
  """Export verification results to CSV."""
532
  try:
533
+ # Check if there are any verifications to export
534
+ verified_count = len([r for r in session.verification_records if r.is_correct is not None])
535
+ if verified_count == 0:
536
+ return """
537
+ <div style="background-color: #fff3cd; padding: 1em; border-radius: 4px;">
538
+ <strong>⚠️ Nothing to Export</strong><br>
539
+ Please verify some exchanges first before exporting.
540
+ </div>
541
+ """
542
+
543
  from src.core.verification_exporter import VerificationExporter
544
  exporter = VerificationExporter()
545
  csv_path = exporter.export_session_to_csv(session)
546
 
547
+ # Get file size for display
548
+ import os
549
+ file_size = os.path.getsize(csv_path) if os.path.exists(csv_path) else 0
550
+ file_size_kb = file_size / 1024
551
+
552
  return f"""
553
  <div style="background-color: #d4edda; padding: 1em; border-radius: 4px;">
554
  <strong>βœ… Export Successful!</strong><br>
555
+ <strong>File:</strong> <code>{os.path.basename(csv_path)}</code><br>
556
+ <strong>Size:</strong> {file_size_kb:.1f} KB<br>
557
+ <strong>Records:</strong> {verified_count} verified exchanges<br>
558
+ <small>πŸ“ Saved to: verification_exports/</small>
559
  </div>
560
  """
561
  except Exception as e:
562
+ print(f"Export error: {e}")
563
+ import traceback
564
+ traceback.print_exc()
565
  return f"""
566
  <div style="background-color: #f8d7da; padding: 1em; border-radius: 4px;">
567
  <strong>❌ Export Failed</strong><br>
568
+ <strong>Error:</strong> {str(e)}<br>
569
+ <small>Check console for details</small>
570
  </div>
571
  """
572
 
 
581
  if session.verification_records[i].is_correct is None:
582
  return i
583
 
584
+ return None # All verified
585
+
586
+ def _mark_all_green_correct(self, session: VerificationSession) -> Tuple[str, str, str, str, int]:
587
+ """Mark all GREEN classifications as correct."""
588
+ try:
589
+ green_records = [r for r in session.verification_records
590
+ if r.original_classification == 'GREEN' and r.is_correct is None]
591
+
592
+ if not green_records:
593
+ return """
594
+ <div style='text-align: center; padding: 2em; background-color: #fff3cd; border-radius: 8px;'>
595
+ <h3>⚠️ No unverified GREEN exchanges</h3>
596
+ <p>All GREEN classifications have already been verified.</p>
597
+ </div>
598
+ """, "No GREEN to verify", "", "", 0
599
+
600
+ print(f"🟒 Marking {len(green_records)} GREEN exchanges as correct...")
601
+
602
+ success_count = 0
603
+ for record in green_records:
604
+ feedback = VerificationFeedback(
605
+ exchange_id=record.exchange_id,
606
+ is_correct=True
607
+ )
608
+ if self.manager.submit_exchange_verification(session.session_id, record.exchange_id, feedback):
609
+ success_count += 1
610
+
611
+ # Reload session
612
+ updated_session = self.manager.load_session(session.session_id)
613
+ if not updated_session:
614
+ return "❌ Failed to reload session", "Error", "", "", 0
615
+
616
+ # Update current session reference
617
+ self.current_session = updated_session
618
+
619
+ # Find next unverified exchange
620
+ next_index = self._find_next_unverified_index(updated_session, -1)
621
+
622
+ if next_index is not None:
623
+ next_record = updated_session.verification_records[next_index]
624
+ exchange_html = self._render_exchange_review(next_record)
625
+ position_html = f"Exchange {next_index + 1} of {len(updated_session.verification_records)}"
626
+ else:
627
+ exchange_html = f"""
628
+ <div style='text-align: center; padding: 2em; background-color: #d4edda; border-radius: 8px;'>
629
+ <h3>πŸŽ‰ GREEN batch verification complete!</h3>
630
+ <p>Marked <strong>{success_count}</strong> GREEN exchanges as correct.</p>
631
+ <p>Continue with remaining exchanges or export results.</p>
632
+ </div>
633
+ """
634
+ position_html = "GREEN Verified"
635
+ next_index = 0
636
+
637
+ stats_html = self._render_statistics(updated_session)
638
+ progress_html = self._render_progress_bar(updated_session)
639
+
640
+ return exchange_html, position_html, stats_html, progress_html, next_index
641
+
642
+ except Exception as e:
643
+ print(f"Error in GREEN batch verification: {e}")
644
+ return f"❌ Error: {str(e)}", "Error", "", "", 0
645
+
646
+ def _skip_to_next_error(self, session: VerificationSession, current_index: int) -> Tuple[str, str, int]:
647
+ """Skip to next exchange that needs attention (unverified or incorrect)."""
648
+ try:
649
+ # Look for next unverified exchange
650
+ next_unverified = self._find_next_unverified_index(session, current_index)
651
+
652
+ if next_unverified is not None:
653
+ record = session.verification_records[next_unverified]
654
+ exchange_html = self._render_exchange_review(record)
655
+ position_html = f"Exchange {next_unverified + 1} of {len(session.verification_records)} (Unverified)"
656
+ return exchange_html, position_html, next_unverified
657
+
658
+ # If no unverified, look for incorrect ones
659
+ for i in range(len(session.verification_records)):
660
+ record = session.verification_records[i]
661
+ if record.is_correct is False:
662
+ exchange_html = self._render_exchange_review(record)
663
+ position_html = f"Exchange {i + 1} of {len(session.verification_records)} (Incorrect)"
664
+ return exchange_html, position_html, i
665
+
666
+ # No errors found
667
+ return """
668
+ <div style='text-align: center; padding: 2em; background-color: #d4edda; border-radius: 8px;'>
669
+ <h3>βœ… No errors found!</h3>
670
+ <p>All exchanges have been verified and are correct.</p>
671
+ </div>
672
+ """, "No Errors", current_index
673
+
674
+ except Exception as e:
675
+ print(f"Error in skip to errors: {e}")
676
+ return f"❌ Error: {str(e)}", "Error", current_index
src/interface/simplified_gradio_app.py CHANGED
@@ -306,6 +306,8 @@ def create_simplified_interface():
306
  with gr.Row():
307
  verify_conversation_btn = gr.Button("πŸ” Verify Conversation", variant="secondary", scale=2, size="sm")
308
 
 
 
309
  # Quick examples
310
  gr.Markdown("### ⚑ Quick Start:")
311
  with gr.Row():
@@ -785,12 +787,20 @@ Changes apply only to your current session.
785
  def open_verification_window(session: SimplifiedSessionData):
786
  """Open verification window for current conversation."""
787
  if session is None or not hasattr(session.app_instance, 'conversation_logger'):
788
- return "❌ No conversation to verify"
 
 
 
789
 
790
  try:
791
  # Check if conversation has any entries
792
  if not session.app_instance.conversation_logger.entries:
793
- return "❌ No conversation exchanges to verify"
 
 
 
 
 
794
 
795
  # Create verification session
796
  from src.core.conversation_verification import ConversationVerificationManager
@@ -802,23 +812,48 @@ Changes apply only to your current session.
802
  "Medical Professional"
803
  )
804
 
 
 
805
  # Create verification interface
806
  interface = VerificationInterface(manager)
807
  verification_window = interface.create_verification_window(verification_session)
808
 
809
- # Launch verification window
810
- verification_window.launch(
811
- server_name="127.0.0.1",
812
- server_port=7861, # Different port from main app
813
- share=False,
814
- show_error=True,
815
- quiet=True
816
- )
 
 
 
 
 
 
817
 
818
- return f"βœ… Verification window opened for {len(verification_session.verification_records)} exchanges"
 
 
 
 
 
 
 
 
 
 
819
 
820
  except Exception as e:
821
- return f"❌ Error opening verification: {str(e)}"
 
 
 
 
 
 
 
822
 
823
  # Prompt editing handlers
824
  def format_prompt_with_html(prompt_text: str) -> str:
@@ -1923,7 +1958,10 @@ To revert, use "Reset to Default" button.
1923
  verify_conversation_btn.click(
1924
  open_verification_window,
1925
  inputs=[session_data],
1926
- outputs=[] # No outputs needed as it opens new window
 
 
 
1927
  )
1928
 
1929
  # Refresh conversation stats
 
306
  with gr.Row():
307
  verify_conversation_btn = gr.Button("πŸ” Verify Conversation", variant="secondary", scale=2, size="sm")
308
 
309
+ verification_status = gr.HTML(value="", visible=False)
310
+
311
  # Quick examples
312
  gr.Markdown("### ⚑ Quick Start:")
313
  with gr.Row():
 
787
  def open_verification_window(session: SimplifiedSessionData):
788
  """Open verification window for current conversation."""
789
  if session is None or not hasattr(session.app_instance, 'conversation_logger'):
790
+ return """<div style="background-color: #f8d7da; padding: 0.75em; border-radius: 4px; margin: 0.5em 0;">
791
+ ❌ <strong>No conversation to verify</strong><br>
792
+ <small>Start a conversation first</small>
793
+ </div>"""
794
 
795
  try:
796
  # Check if conversation has any entries
797
  if not session.app_instance.conversation_logger.entries:
798
+ return """<div style="background-color: #fff3cd; padding: 0.75em; border-radius: 4px; margin: 0.5em 0;">
799
+ ⚠️ <strong>No conversation exchanges to verify</strong><br>
800
+ <small>Send some messages in the chat first</small>
801
+ </div>"""
802
+
803
+ print(f"πŸ” Opening verification for {len(session.app_instance.conversation_logger.entries)} exchanges...")
804
 
805
  # Create verification session
806
  from src.core.conversation_verification import ConversationVerificationManager
 
812
  "Medical Professional"
813
  )
814
 
815
+ print(f"βœ… Created verification session: {verification_session.session_id}")
816
+
817
  # Create verification interface
818
  interface = VerificationInterface(manager)
819
  verification_window = interface.create_verification_window(verification_session)
820
 
821
+ # Try to launch verification window in background
822
+ import threading
823
+ def launch_verification():
824
+ try:
825
+ verification_window.launch(
826
+ server_name="127.0.0.1",
827
+ server_port=7861, # Different port from main app
828
+ share=False,
829
+ show_error=True,
830
+ quiet=False,
831
+ prevent_thread_lock=True
832
+ )
833
+ except Exception as e:
834
+ print(f"❌ Error launching verification window: {e}")
835
 
836
+ # Launch in separate thread
837
+ thread = threading.Thread(target=launch_verification, daemon=True)
838
+ thread.start()
839
+
840
+ print(f"βœ… Verification window should open at http://127.0.0.1:7861")
841
+
842
+ return f"""<div style="background-color: #d4edda; padding: 0.75em; border-radius: 4px; margin: 0.5em 0;">
843
+ βœ… <strong>Verification window opening...</strong><br>
844
+ <small>Verifying {len(verification_session.verification_records)} exchanges</small><br>
845
+ <small>Check: <a href="http://127.0.0.1:7861" target="_blank">http://127.0.0.1:7861</a></small>
846
+ </div>"""
847
 
848
  except Exception as e:
849
+ print(f"❌ Error opening verification: {str(e)}")
850
+ import traceback
851
+ traceback.print_exc()
852
+
853
+ return f"""<div style="background-color: #f8d7da; padding: 0.75em; border-radius: 4px; margin: 0.5em 0;">
854
+ ❌ <strong>Error opening verification</strong><br>
855
+ <small>{str(e)}</small>
856
+ </div>"""
857
 
858
  # Prompt editing handlers
859
  def format_prompt_with_html(prompt_text: str) -> str:
 
1958
  verify_conversation_btn.click(
1959
  open_verification_window,
1960
  inputs=[session_data],
1961
+ outputs=[verification_status]
1962
+ ).then(
1963
+ lambda: gr.HTML(visible=True),
1964
+ outputs=[verification_status]
1965
  )
1966
 
1967
  # Refresh conversation stats