SamanthaStorm commited on
Commit
5a21664
·
verified ·
1 Parent(s): be824f1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -0
app.py CHANGED
@@ -113,6 +113,70 @@ def generate_risk_snippet(abuse_score, top_label, escalation_score):
113
  base += "🧠 You can review the pattern in context. This tool highlights possible dynamics—not judgments."
114
 
115
  return base
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  textbox_inputs = [gr.Textbox(label=f"Message {i+1}") for i in range(3)]
117
  quiz_boxes = [gr.Checkbox(label=q) for q, _ in ESCALATION_QUESTIONS]
118
  none_box = gr.Checkbox(label="None of the above")
 
113
  base += "🧠 You can review the pattern in context. This tool highlights possible dynamics—not judgments."
114
 
115
  return base
116
+ def analyze_single_message(text, thresholds):
117
+ motif_hits, matched_phrases = detect_motifs(text)
118
+ result = sst_pipeline(text)[0]
119
+ sentiment = "supportive" if result['label'] == "POSITIVE" else "undermining"
120
+ sentiment_score = result['score'] if sentiment == "undermining" else 0.0
121
+
122
+ adjusted_thresholds = {
123
+ k: v + 0.05 if sentiment == "supportive" else v
124
+ for k, v in thresholds.items()
125
+ }
126
+
127
+ contradiction_flag = detect_contradiction(text)
128
+ motifs = [phrase for _, phrase in matched_phrases]
129
+
130
+ inputs = tokenizer(text, return_tensors="pt", truncation=True, padding=True)
131
+ with torch.no_grad():
132
+ outputs = model(**inputs)
133
+ scores = torch.sigmoid(outputs.logits.squeeze(0)).numpy()
134
+
135
+ threshold_labels = [
136
+ label for label, score in zip(LABELS, scores)
137
+ if score > adjusted_thresholds[label]
138
+ ]
139
+
140
+ top_patterns = sorted(
141
+ [(label, score) for label, score in zip(LABELS, scores)],
142
+ key=lambda x: x[1],
143
+ reverse=True
144
+ )[:2]
145
+
146
+ weighted_scores = [(PATTERN_WEIGHTS.get(label, 1.0) * score) for label, score in top_patterns]
147
+ abuse_score = min(np.mean(weighted_scores) * 100, 100)
148
+
149
+ stage = get_risk_stage(threshold_labels, sentiment)
150
+
151
+ return abuse_score, threshold_labels, top_patterns, result, stage
152
+
153
+ def analyze_composite(msg1, msg2, msg3, *answers_and_none):
154
+ responses = answers_and_none[:len(ESCALATION_QUESTIONS)]
155
+ none_selected = answers_and_none[-1]
156
+ escalation_score = 0 if none_selected else sum(w for (_, w), a in zip(ESCALATION_QUESTIONS, responses) if a)
157
+ messages = [msg1, msg2, msg3]
158
+ active = [m for m in messages if m.strip()]
159
+ if not active:
160
+ return "Please enter at least one message."
161
+
162
+ results = [analyze_single_message(m, THRESHOLDS.copy()) for m in active]
163
+ abuse_scores = [r[0] for r in results]
164
+ top_labels = [r[2][0][0] for r in results]
165
+ top_scores = [r[2][0][1] for r in results]
166
+ sentiments = [r[3]['label'] for r in results]
167
+ stages = [r[4] for r in results]
168
+
169
+ most_common_stage = max(set(stages), key=stages.count)
170
+ stage_text = RISK_STAGE_LABELS[most_common_stage]
171
+
172
+ top_label = f"{top_labels[0]} – {int(round(top_scores[0] * 100))}%"
173
+ composite_abuse = int(round(sum(abuse_scores) / len(abuse_scores)))
174
+
175
+ out = f"Abuse Intensity: {composite_abuse}%\n"
176
+ out += f"Escalation Potential: {('High' if escalation_score >= 16 else 'Moderate' if escalation_score >= 8 else 'Low')} ({escalation_score}/{sum(w for _, w in ESCALATION_QUESTIONS)})"
177
+ out += generate_risk_snippet(composite_abuse, top_label, escalation_score)
178
+ out += f"\n\n{stage_text}"
179
+ return out
180
  textbox_inputs = [gr.Textbox(label=f"Message {i+1}") for i in range(3)]
181
  quiz_boxes = [gr.Checkbox(label=q) for q, _ in ESCALATION_QUESTIONS]
182
  none_box = gr.Checkbox(label="None of the above")