Spaces:
Running
on
Zero
Running
on
Zero
Update app.py
Browse files
app.py
CHANGED
@@ -528,6 +528,13 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
528 |
"""Analyze multiple messages and checklist responses"""
|
529 |
logger.debug("\nπ STARTING NEW ANALYSIS")
|
530 |
logger.debug("=" * 50)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
531 |
try:
|
532 |
# Process checklist responses
|
533 |
logger.debug("\nπ CHECKLIST PROCESSING")
|
@@ -577,6 +584,7 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
577 |
# Detect threats
|
578 |
logger.debug("\nπ¨ THREAT DETECTION")
|
579 |
logger.debug("=" * 50)
|
|
|
580 |
def normalize(text):
|
581 |
import unicodedata
|
582 |
text = text.lower().strip()
|
@@ -592,13 +600,6 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
592 |
immediate_threats = [detect_threat_motifs(m, THREAT_MOTIFS) for m, _ in active]
|
593 |
flat_threats = [t for sublist in immediate_threats for t in sublist]
|
594 |
threat_risk = "Yes" if flat_threats else "No"
|
595 |
-
|
596 |
-
if flat_threats:
|
597 |
-
logger.debug("β οΈ DETECTED THREATS:")
|
598 |
-
for threat in flat_threats:
|
599 |
-
logger.debug(f" β’ {threat}")
|
600 |
-
else:
|
601 |
-
logger.debug("β No explicit threats detected")
|
602 |
# Analyze each message
|
603 |
logger.debug("\nπ INDIVIDUAL MESSAGE ANALYSIS")
|
604 |
logger.debug("=" * 50)
|
@@ -636,21 +637,35 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
636 |
tone_tags = [r[0][6] for r in results]
|
637 |
dates_used = [r[1] for r in results]
|
638 |
|
639 |
-
# Pattern Analysis
|
640 |
logger.debug("\nπ PATTERN ANALYSIS SUMMARY")
|
641 |
logger.debug("=" * 50)
|
642 |
predicted_labels = [label for r in results for label in r[0][1]]
|
643 |
|
644 |
if predicted_labels:
|
645 |
logger.debug("Detected Patterns Across All Messages:")
|
646 |
-
|
647 |
-
|
648 |
-
|
649 |
-
|
650 |
-
|
651 |
-
|
652 |
-
|
653 |
-
logger.debug(f"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
654 |
else:
|
655 |
logger.debug("β No patterns detected across messages")
|
656 |
|
@@ -667,30 +682,49 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
667 |
counts['low'] += 1
|
668 |
|
669 |
logger.debug("Pattern Distribution:")
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
674 |
# Risk Assessment
|
675 |
logger.debug("\nπ― RISK ASSESSMENT")
|
676 |
logger.debug("=" * 50)
|
677 |
if counts['high'] >= 2 and counts['moderate'] >= 2:
|
678 |
pattern_escalation_risk = "Critical"
|
679 |
-
logger.debug("
|
|
|
|
|
|
|
680 |
elif (counts['high'] >= 2 and counts['moderate'] >= 1) or \
|
681 |
(counts['moderate'] >= 3) or \
|
682 |
(counts['high'] >= 1 and counts['moderate'] >= 2):
|
683 |
pattern_escalation_risk = "High"
|
684 |
-
logger.debug("
|
|
|
|
|
|
|
685 |
elif (counts['moderate'] == 2) or \
|
686 |
(counts['high'] == 1 and counts['moderate'] == 1) or \
|
687 |
(counts['moderate'] == 1 and counts['low'] >= 2) or \
|
688 |
(counts['high'] == 1 and sum(counts.values()) == 1):
|
689 |
pattern_escalation_risk = "Moderate"
|
690 |
-
logger.debug("
|
|
|
|
|
691 |
else:
|
692 |
pattern_escalation_risk = "Low"
|
693 |
-
logger.debug("π LOW RISK
|
|
|
|
|
694 |
|
695 |
# Checklist Risk Assessment
|
696 |
logger.debug("\nπ CHECKLIST RISK ASSESSMENT")
|
@@ -700,21 +734,30 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
700 |
"Moderate" if escalation_score >= 10 else
|
701 |
"Low"
|
702 |
)
|
703 |
-
logger.debug(f"Risk Level: {checklist_escalation_risk}")
|
704 |
if escalation_score is not None:
|
705 |
logger.debug(f"Score: {escalation_score}/29")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
706 |
# Escalation Analysis
|
707 |
logger.debug("\nπ ESCALATION ANALYSIS")
|
708 |
logger.debug("=" * 50)
|
709 |
escalation_bump = 0
|
710 |
for result, msg_id in results:
|
711 |
abuse_score, _, _, sentiment, stage, darvo_score, tone_tag = result
|
712 |
-
logger.debug(f"\nπ Message {msg_id}
|
713 |
|
714 |
factors = []
|
715 |
if darvo_score > 0.65:
|
716 |
escalation_bump += 3
|
717 |
-
factors.append("β² +3: High DARVO score ({darvo_score:.3f})")
|
718 |
if tone_tag in ["forced accountability flip", "emotional threat"]:
|
719 |
escalation_bump += 2
|
720 |
factors.append(f"β² +2: Concerning tone ({tone_tag})")
|
@@ -741,8 +784,8 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
741 |
|
742 |
combined_score = rank(pattern_escalation_risk) + rank(checklist_escalation_risk) + escalation_bump
|
743 |
logger.debug("Risk Components:")
|
744 |
-
logger.debug(f" β’ Pattern Risk
|
745 |
-
logger.debug(f" β’ Checklist Risk
|
746 |
logger.debug(f" β’ Escalation Bump: +{escalation_bump}")
|
747 |
logger.debug(f" = Combined Score: {combined_score}")
|
748 |
|
@@ -753,7 +796,6 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
753 |
"Low"
|
754 |
)
|
755 |
logger.debug(f"\nβ οΈ Final Escalation Risk: {escalation_risk}")
|
756 |
-
|
757 |
# Generate Output Text
|
758 |
logger.debug("\nπ GENERATING OUTPUT")
|
759 |
logger.debug("=" * 50)
|
@@ -797,7 +839,7 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
797 |
avg_darvo = round(sum(darvo_scores) / len(darvo_scores), 3)
|
798 |
logger.debug(f"Average DARVO Score: {avg_darvo}")
|
799 |
|
800 |
-
# Generate Final
|
801 |
logger.debug("\nπ GENERATING FINAL REPORT")
|
802 |
logger.debug("=" * 50)
|
803 |
out = f"Abuse Intensity: {composite_abuse}%\n"
|
@@ -838,6 +880,7 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
838 |
|
839 |
out += risk_descriptions[risk_level]
|
840 |
out += f"\n\n{RISK_STAGE_LABELS[most_common_stage]}"
|
|
|
841 |
|
842 |
# Add DARVO Analysis
|
843 |
if avg_darvo > 0.25:
|
@@ -859,7 +902,7 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
859 |
for t in set(flat_threats):
|
860 |
out += f"β’ \"{t}\"\n"
|
861 |
out += "\nβ οΈ These phrases may indicate an imminent risk to physical safety."
|
862 |
-
logger.debug(f"Added {len(flat_threats)} threat warnings")
|
863 |
else:
|
864 |
out += "\n\nπ§© **Immediate Danger Threats:** None explicitly detected.\n"
|
865 |
out += "This does *not* rule out risk, but no direct threat phrases were matched."
|
@@ -876,6 +919,7 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
876 |
|
877 |
# Add Escalation Text
|
878 |
out += "\n\n" + escalation_text
|
|
|
879 |
|
880 |
logger.debug("\nβ
ANALYSIS COMPLETE")
|
881 |
logger.debug("=" * 50)
|
@@ -891,6 +935,7 @@ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
|
|
891 |
|
892 |
|
893 |
|
|
|
894 |
# Gradio Interface Setup
|
895 |
def create_interface():
|
896 |
try:
|
|
|
528 |
"""Analyze multiple messages and checklist responses"""
|
529 |
logger.debug("\nπ STARTING NEW ANALYSIS")
|
530 |
logger.debug("=" * 50)
|
531 |
+
|
532 |
+
# Define severity categories at the start
|
533 |
+
high = {'control'}
|
534 |
+
moderate = {'gaslighting', 'dismissiveness', 'obscure language', 'insults',
|
535 |
+
'contradictory statements', 'guilt tripping'}
|
536 |
+
low = {'blame shifting', 'projection', 'recovery'}
|
537 |
+
|
538 |
try:
|
539 |
# Process checklist responses
|
540 |
logger.debug("\nπ CHECKLIST PROCESSING")
|
|
|
584 |
# Detect threats
|
585 |
logger.debug("\nπ¨ THREAT DETECTION")
|
586 |
logger.debug("=" * 50)
|
587 |
+
|
588 |
def normalize(text):
|
589 |
import unicodedata
|
590 |
text = text.lower().strip()
|
|
|
600 |
immediate_threats = [detect_threat_motifs(m, THREAT_MOTIFS) for m, _ in active]
|
601 |
flat_threats = [t for sublist in immediate_threats for t in sublist]
|
602 |
threat_risk = "Yes" if flat_threats else "No"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
603 |
# Analyze each message
|
604 |
logger.debug("\nπ INDIVIDUAL MESSAGE ANALYSIS")
|
605 |
logger.debug("=" * 50)
|
|
|
637 |
tone_tags = [r[0][6] for r in results]
|
638 |
dates_used = [r[1] for r in results]
|
639 |
|
640 |
+
# Pattern Analysis Summary
|
641 |
logger.debug("\nπ PATTERN ANALYSIS SUMMARY")
|
642 |
logger.debug("=" * 50)
|
643 |
predicted_labels = [label for r in results for label in r[0][1]]
|
644 |
|
645 |
if predicted_labels:
|
646 |
logger.debug("Detected Patterns Across All Messages:")
|
647 |
+
pattern_counts = Counter(predicted_labels)
|
648 |
+
|
649 |
+
# Log high severity patterns first
|
650 |
+
high_patterns = [p for p in pattern_counts if p in high]
|
651 |
+
if high_patterns:
|
652 |
+
logger.debug("\nβ HIGH SEVERITY PATTERNS:")
|
653 |
+
for p in high_patterns:
|
654 |
+
logger.debug(f" β’ {p} (Γ{pattern_counts[p]})")
|
655 |
+
|
656 |
+
# Then moderate
|
657 |
+
moderate_patterns = [p for p in pattern_counts if p in moderate]
|
658 |
+
if moderate_patterns:
|
659 |
+
logger.debug("\nβ οΈ MODERATE SEVERITY PATTERNS:")
|
660 |
+
for p in moderate_patterns:
|
661 |
+
logger.debug(f" β’ {p} (Γ{pattern_counts[p]})")
|
662 |
+
|
663 |
+
# Then low
|
664 |
+
low_patterns = [p for p in pattern_counts if p in low]
|
665 |
+
if low_patterns:
|
666 |
+
logger.debug("\nπ LOW SEVERITY PATTERNS:")
|
667 |
+
for p in low_patterns:
|
668 |
+
logger.debug(f" β’ {p} (Γ{pattern_counts[p]})")
|
669 |
else:
|
670 |
logger.debug("β No patterns detected across messages")
|
671 |
|
|
|
682 |
counts['low'] += 1
|
683 |
|
684 |
logger.debug("Pattern Distribution:")
|
685 |
+
if counts['high'] > 0:
|
686 |
+
logger.debug(f" β High Severity: {counts['high']}")
|
687 |
+
if counts['moderate'] > 0:
|
688 |
+
logger.debug(f" β οΈ Moderate Severity: {counts['moderate']}")
|
689 |
+
if counts['low'] > 0:
|
690 |
+
logger.debug(f" π Low Severity: {counts['low']}")
|
691 |
+
|
692 |
+
total_patterns = sum(counts.values())
|
693 |
+
if total_patterns > 0:
|
694 |
+
logger.debug(f"\nSeverity Percentages:")
|
695 |
+
logger.debug(f" β’ High: {(counts['high']/total_patterns)*100:.1f}%")
|
696 |
+
logger.debug(f" β’ Moderate: {(counts['moderate']/total_patterns)*100:.1f}%")
|
697 |
+
logger.debug(f" β’ Low: {(counts['low']/total_patterns)*100:.1f}%")
|
698 |
# Risk Assessment
|
699 |
logger.debug("\nπ― RISK ASSESSMENT")
|
700 |
logger.debug("=" * 50)
|
701 |
if counts['high'] >= 2 and counts['moderate'] >= 2:
|
702 |
pattern_escalation_risk = "Critical"
|
703 |
+
logger.debug("ββ CRITICAL RISK")
|
704 |
+
logger.debug(" β’ Multiple high and moderate patterns detected")
|
705 |
+
logger.debug(f" β’ High patterns: {counts['high']}")
|
706 |
+
logger.debug(f" β’ Moderate patterns: {counts['moderate']}")
|
707 |
elif (counts['high'] >= 2 and counts['moderate'] >= 1) or \
|
708 |
(counts['moderate'] >= 3) or \
|
709 |
(counts['high'] >= 1 and counts['moderate'] >= 2):
|
710 |
pattern_escalation_risk = "High"
|
711 |
+
logger.debug("β HIGH RISK")
|
712 |
+
logger.debug(" β’ Significant pattern combination detected")
|
713 |
+
logger.debug(f" β’ High patterns: {counts['high']}")
|
714 |
+
logger.debug(f" β’ Moderate patterns: {counts['moderate']}")
|
715 |
elif (counts['moderate'] == 2) or \
|
716 |
(counts['high'] == 1 and counts['moderate'] == 1) or \
|
717 |
(counts['moderate'] == 1 and counts['low'] >= 2) or \
|
718 |
(counts['high'] == 1 and sum(counts.values()) == 1):
|
719 |
pattern_escalation_risk = "Moderate"
|
720 |
+
logger.debug("β οΈ MODERATE RISK")
|
721 |
+
logger.debug(" β’ Concerning pattern combination detected")
|
722 |
+
logger.debug(f" β’ Pattern distribution: H:{counts['high']}, M:{counts['moderate']}, L:{counts['low']}")
|
723 |
else:
|
724 |
pattern_escalation_risk = "Low"
|
725 |
+
logger.debug("π LOW RISK")
|
726 |
+
logger.debug(" β’ Limited pattern severity detected")
|
727 |
+
logger.debug(f" β’ Pattern distribution: H:{counts['high']}, M:{counts['moderate']}, L:{counts['low']}")
|
728 |
|
729 |
# Checklist Risk Assessment
|
730 |
logger.debug("\nπ CHECKLIST RISK ASSESSMENT")
|
|
|
734 |
"Moderate" if escalation_score >= 10 else
|
735 |
"Low"
|
736 |
)
|
|
|
737 |
if escalation_score is not None:
|
738 |
logger.debug(f"Score: {escalation_score}/29")
|
739 |
+
logger.debug(f"Risk Level: {checklist_escalation_risk}")
|
740 |
+
if escalation_score >= 20:
|
741 |
+
logger.debug("ββ CRITICAL: Score indicates severe risk")
|
742 |
+
elif escalation_score >= 10:
|
743 |
+
logger.debug("β οΈ MODERATE: Score indicates concerning risk")
|
744 |
+
else:
|
745 |
+
logger.debug("π LOW: Score indicates limited risk")
|
746 |
+
else:
|
747 |
+
logger.debug("β Risk Level: Unknown (checklist not completed)")
|
748 |
+
|
749 |
# Escalation Analysis
|
750 |
logger.debug("\nπ ESCALATION ANALYSIS")
|
751 |
logger.debug("=" * 50)
|
752 |
escalation_bump = 0
|
753 |
for result, msg_id in results:
|
754 |
abuse_score, _, _, sentiment, stage, darvo_score, tone_tag = result
|
755 |
+
logger.debug(f"\nπ Message {msg_id} Risk Factors:")
|
756 |
|
757 |
factors = []
|
758 |
if darvo_score > 0.65:
|
759 |
escalation_bump += 3
|
760 |
+
factors.append(f"β² +3: High DARVO score ({darvo_score:.3f})")
|
761 |
if tone_tag in ["forced accountability flip", "emotional threat"]:
|
762 |
escalation_bump += 2
|
763 |
factors.append(f"β² +2: Concerning tone ({tone_tag})")
|
|
|
784 |
|
785 |
combined_score = rank(pattern_escalation_risk) + rank(checklist_escalation_risk) + escalation_bump
|
786 |
logger.debug("Risk Components:")
|
787 |
+
logger.debug(f" β’ Pattern Risk ({pattern_escalation_risk}): +{rank(pattern_escalation_risk)}")
|
788 |
+
logger.debug(f" β’ Checklist Risk ({checklist_escalation_risk}): +{rank(checklist_escalation_risk)}")
|
789 |
logger.debug(f" β’ Escalation Bump: +{escalation_bump}")
|
790 |
logger.debug(f" = Combined Score: {combined_score}")
|
791 |
|
|
|
796 |
"Low"
|
797 |
)
|
798 |
logger.debug(f"\nβ οΈ Final Escalation Risk: {escalation_risk}")
|
|
|
799 |
# Generate Output Text
|
800 |
logger.debug("\nπ GENERATING OUTPUT")
|
801 |
logger.debug("=" * 50)
|
|
|
839 |
avg_darvo = round(sum(darvo_scores) / len(darvo_scores), 3)
|
840 |
logger.debug(f"Average DARVO Score: {avg_darvo}")
|
841 |
|
842 |
+
# Generate Final Report
|
843 |
logger.debug("\nπ GENERATING FINAL REPORT")
|
844 |
logger.debug("=" * 50)
|
845 |
out = f"Abuse Intensity: {composite_abuse}%\n"
|
|
|
880 |
|
881 |
out += risk_descriptions[risk_level]
|
882 |
out += f"\n\n{RISK_STAGE_LABELS[most_common_stage]}"
|
883 |
+
logger.debug("Added risk description and stage information")
|
884 |
|
885 |
# Add DARVO Analysis
|
886 |
if avg_darvo > 0.25:
|
|
|
902 |
for t in set(flat_threats):
|
903 |
out += f"β’ \"{t}\"\n"
|
904 |
out += "\nβ οΈ These phrases may indicate an imminent risk to physical safety."
|
905 |
+
logger.debug(f"Added {len(set(flat_threats))} unique threat warnings")
|
906 |
else:
|
907 |
out += "\n\nπ§© **Immediate Danger Threats:** None explicitly detected.\n"
|
908 |
out += "This does *not* rule out risk, but no direct threat phrases were matched."
|
|
|
919 |
|
920 |
# Add Escalation Text
|
921 |
out += "\n\n" + escalation_text
|
922 |
+
logger.debug("Added escalation text to output")
|
923 |
|
924 |
logger.debug("\nβ
ANALYSIS COMPLETE")
|
925 |
logger.debug("=" * 50)
|
|
|
935 |
|
936 |
|
937 |
|
938 |
+
|
939 |
# Gradio Interface Setup
|
940 |
def create_interface():
|
941 |
try:
|