Justadudeinspace commited on
Commit
d4fb03b
·
unverified ·
1 Parent(s): 7cc8932

Add app demo of BLUX-cA

Browse files
Files changed (1) hide show
  1. app.py +90 -37
app.py CHANGED
@@ -20,7 +20,7 @@ Run:
20
  """
21
 
22
  from __future__ import annotations
23
- import json, re, time, uuid, logging
24
  from dataclasses import dataclass, asdict
25
  from pathlib import Path
26
  from typing import Dict, List, Tuple, Optional, Any
@@ -272,13 +272,31 @@ class SessionManager:
272
  def __init__(self):
273
  self.session_id = str(uuid.uuid4())
274
  self.start_time = time.time()
 
 
275
 
276
  def get_session_info(self) -> Dict[str, Any]:
277
  return {
278
  "session_id": self.session_id,
279
  "start_time": self.start_time,
280
- "duration": time.time() - self.start_time
 
281
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
  session_manager = SessionManager()
284
 
@@ -307,7 +325,7 @@ def ca_chat(
307
  message: str,
308
  enable_redaction: bool,
309
  gentle_tone: bool,
310
- log_path: str
311
  ) -> Tuple[List[Dict[str, str]], Dict[str, Any], Optional[str]]:
312
  """
313
  Enhanced chat handler with proper Gradio messages format and error handling.
@@ -365,17 +383,30 @@ def ca_chat(
365
  audit_event = make_audit_event(clean_message, found_redactions, compass_result, reply)
366
  audit_dict = asdict(audit_event)
367
 
368
- if log_path:
 
 
369
  try:
370
- log_file = Path(log_path).expanduser()
371
- log_file.parent.mkdir(parents=True, exist_ok=True)
372
- with log_file.open("a", encoding="utf-8") as f:
373
  f.write(json.dumps(audit_dict, ensure_ascii=False) + "\n")
374
- logger.info(f"Audit event written to {log_file}")
 
375
  except Exception as e:
376
- logger.error(f"Failed to write audit log: {e}")
 
 
 
 
 
 
 
 
 
 
377
 
378
- return updated_history, audit_dict, str(log_file) if log_path and log_file.exists() else None
379
 
380
  except Exception as e:
381
  logger.error(f"Error in ca_chat: {e}")
@@ -440,6 +471,11 @@ def build_ui():
440
  label="🌱 Gentle tone mode",
441
  info="Softer, more supportive language"
442
  )
 
 
 
 
 
443
 
444
  with gr.Row():
445
  send_btn = gr.Button("Send", variant="primary", size="lg")
@@ -465,41 +501,43 @@ def build_ui():
465
  value={}
466
  )
467
 
468
- log_file = gr.Textbox(
469
- value="~/.outer_void/audit/blux_ca_demo.jsonl",
470
- label="Audit Log Path",
471
- info="JSONL file for append-only logging"
472
- )
473
-
474
  download = gr.File(
475
- label="Download Audit Log",
476
- visible=False
 
 
477
  )
478
 
479
  # Event handlers
480
- def on_send(history, message, redact_enabled, gentle_enabled, log_path):
481
  if not message or not message.strip():
482
  gr.Warning("Please enter a message before sending.")
483
  return history, {}, None, session_manager.get_session_info()
484
 
485
  new_history, audit_data, download_path = ca_chat(
486
- history or [], message, redact_enabled, gentle_enabled, log_path
487
  )
488
 
489
  session_info = session_manager.get_session_info()
490
- download_component = download_path if download_path else None
491
 
492
- return new_history, audit_data, download_component, session_info
 
 
 
 
493
 
494
  def on_clear():
495
- session_manager.session_id = str(uuid.uuid4())
496
- session_manager.start_time = time.time()
497
- return [], {}, None, session_manager.get_session_info()
 
 
498
 
499
  # Connect components
500
  send_btn.click(
501
  fn=on_send,
502
- inputs=[chat, msg, redact_toggle, gentle_tone, log_file],
503
  outputs=[chat, audit_json, download, session_info]
504
  ).then(
505
  lambda: "", # Clear message input
@@ -508,7 +546,7 @@ def build_ui():
508
 
509
  msg.submit(
510
  fn=on_send,
511
- inputs=[chat, msg, redact_toggle, gentle_tone, log_file],
512
  outputs=[chat, audit_json, download, session_info]
513
  ).then(
514
  lambda: "", # Clear message input
@@ -532,6 +570,11 @@ def build_ui():
532
  **Safety First**: Automatic crisis detection with immediate resource guidance
533
 
534
  **Privacy**: Optional redaction of personal information before processing
 
 
 
 
 
535
  """)
536
 
537
  return demo
@@ -548,13 +591,23 @@ if __name__ == "__main__":
548
  logger.error("Gradio not installed. Run: pip install gradio>=4.44.0")
549
  exit(1)
550
 
551
- # Launch the application
552
- demo = build_ui()
553
- demo.launch(
554
- server_name="0.0.0.0",
555
- server_port=7860,
556
- share=False,
557
- show_error=True,
558
- debug=False,
559
- ssr_mode=False
560
- )
 
 
 
 
 
 
 
 
 
 
 
20
  """
21
 
22
  from __future__ import annotations
23
+ import json, re, time, uuid, logging, tempfile, shutil
24
  from dataclasses import dataclass, asdict
25
  from pathlib import Path
26
  from typing import Dict, List, Tuple, Optional, Any
 
272
  def __init__(self):
273
  self.session_id = str(uuid.uuid4())
274
  self.start_time = time.time()
275
+ self.temp_dir = Path(tempfile.mkdtemp(prefix="blux_ca_"))
276
+ logger.info(f"Session temp directory: {self.temp_dir}")
277
 
278
  def get_session_info(self) -> Dict[str, Any]:
279
  return {
280
  "session_id": self.session_id,
281
  "start_time": self.start_time,
282
+ "duration": round(time.time() - self.start_time, 2),
283
+ "temp_dir": str(self.temp_dir)
284
  }
285
+
286
+ def create_temp_audit_file(self) -> Path:
287
+ """Create a temporary audit file that Gradio can safely serve."""
288
+ audit_file = self.temp_dir / f"blux_ca_audit_{self.session_id}.jsonl"
289
+ audit_file.touch()
290
+ return audit_file
291
+
292
+ def cleanup(self):
293
+ """Clean up temporary files."""
294
+ try:
295
+ if self.temp_dir.exists():
296
+ shutil.rmtree(self.temp_dir)
297
+ logger.info(f"Cleaned up temp directory: {self.temp_dir}")
298
+ except Exception as e:
299
+ logger.warning(f"Failed to clean up temp directory: {e}")
300
 
301
  session_manager = SessionManager()
302
 
 
325
  message: str,
326
  enable_redaction: bool,
327
  gentle_tone: bool,
328
+ use_temp_logging: bool # New parameter to control logging location
329
  ) -> Tuple[List[Dict[str, str]], Dict[str, Any], Optional[str]]:
330
  """
331
  Enhanced chat handler with proper Gradio messages format and error handling.
 
383
  audit_event = make_audit_event(clean_message, found_redactions, compass_result, reply)
384
  audit_dict = asdict(audit_event)
385
 
386
+ download_path = None
387
+
388
+ if use_temp_logging:
389
  try:
390
+ # Use temporary directory that Gradio can access
391
+ temp_audit_file = session_manager.create_temp_audit_file()
392
+ with temp_audit_file.open("a", encoding="utf-8") as f:
393
  f.write(json.dumps(audit_dict, ensure_ascii=False) + "\n")
394
+ download_path = str(temp_audit_file)
395
+ logger.info(f"Audit event written to temporary file: {temp_audit_file}")
396
  except Exception as e:
397
+ logger.error(f"Failed to write temporary audit log: {e}")
398
+ else:
399
+ # Original logging to custom path (without download capability)
400
+ try:
401
+ log_path = Path("~/.outer_void/audit/blux_ca_demo.jsonl").expanduser()
402
+ log_path.parent.mkdir(parents=True, exist_ok=True)
403
+ with log_path.open("a", encoding="utf-8") as f:
404
+ f.write(json.dumps(audit_dict, ensure_ascii=False) + "\n")
405
+ logger.info(f"Audit event written to persistent log: {log_path}")
406
+ except Exception as e:
407
+ logger.error(f"Failed to write persistent audit log: {e}")
408
 
409
+ return updated_history, audit_dict, download_path
410
 
411
  except Exception as e:
412
  logger.error(f"Error in ca_chat: {e}")
 
471
  label="🌱 Gentle tone mode",
472
  info="Softer, more supportive language"
473
  )
474
+ temp_logging = gr.Checkbox(
475
+ True,
476
+ label="📥 Enable file downloads",
477
+ info="Allows downloading audit logs (uses temp files)"
478
+ )
479
 
480
  with gr.Row():
481
  send_btn = gr.Button("Send", variant="primary", size="lg")
 
501
  value={}
502
  )
503
 
504
+ gr.Markdown("### 💾 Download Audit Log")
 
 
 
 
 
505
  download = gr.File(
506
+ label="Session Audit Log",
507
+ visible=False,
508
+ file_types=[".jsonl"],
509
+ type="filepath"
510
  )
511
 
512
  # Event handlers
513
+ def on_send(history, message, redact_enabled, gentle_enabled, temp_logging_enabled):
514
  if not message or not message.strip():
515
  gr.Warning("Please enter a message before sending.")
516
  return history, {}, None, session_manager.get_session_info()
517
 
518
  new_history, audit_data, download_path = ca_chat(
519
+ history or [], message, redact_enabled, gentle_enabled, temp_logging_enabled
520
  )
521
 
522
  session_info = session_manager.get_session_info()
 
523
 
524
+ # Show download button only if we have a downloadable file
525
+ download_visible = download_path is not None
526
+ download_value = download_path if download_path else None
527
+
528
+ return new_history, audit_data, gr.update(visible=download_visible, value=download_value), session_info
529
 
530
  def on_clear():
531
+ # Clean up old session and start new one
532
+ session_manager.cleanup()
533
+ session_manager.__init__() # Reinitialize for new session
534
+
535
+ return [], {}, gr.update(visible=False, value=None), session_manager.get_session_info()
536
 
537
  # Connect components
538
  send_btn.click(
539
  fn=on_send,
540
+ inputs=[chat, msg, redact_toggle, gentle_tone, temp_logging],
541
  outputs=[chat, audit_json, download, session_info]
542
  ).then(
543
  lambda: "", # Clear message input
 
546
 
547
  msg.submit(
548
  fn=on_send,
549
+ inputs=[chat, msg, redact_toggle, gentle_tone, temp_logging],
550
  outputs=[chat, audit_json, download, session_info]
551
  ).then(
552
  lambda: "", # Clear message input
 
570
  **Safety First**: Automatic crisis detection with immediate resource guidance
571
 
572
  **Privacy**: Optional redaction of personal information before processing
573
+
574
+ ### 📁 File Downloads
575
+
576
+ Enable "Download Audit Logs" to get a JSONL file containing all conversation events.
577
+ Files are stored in a temporary directory and cleaned up when you clear the history.
578
  """)
579
 
580
  return demo
 
591
  logger.error("Gradio not installed. Run: pip install gradio>=4.44.0")
592
  exit(1)
593
 
594
+ try:
595
+ # Launch the application with allowed paths for file downloads
596
+ demo = build_ui()
597
+ demo.launch(
598
+ server_name="0.0.0.0",
599
+ server_port=7860,
600
+ share=False,
601
+ show_error=True,
602
+ debug=False,
603
+ ssr_mode=False,
604
+ # Allow temp directory access for file downloads
605
+ allowed_paths=[session_manager.temp_dir]
606
+ )
607
+ except KeyboardInterrupt:
608
+ logger.info("Received interrupt signal - shutting down gracefully...")
609
+ except Exception as e:
610
+ logger.error(f"Failed to launch application: {e}")
611
+ finally:
612
+ # Clean up on exit
613
+ session_manager.cleanup()