import gradio as gr # Define detection patterns patterns = [ { "id": "identity_erosion_001", "name": "Loss of Personal Joy", "trigger_keywords": ["used to love", "don’t anymore", "haven’t done that in years", "stopped doing"], "concern": "Identity erosion / subtle control", "follow_up_therapist": "What made you stop?", "follow_up_cop": "When did you stop doing that, and did anyone tell you not to?", "insight": "Loss of joyful or self-expressive activities may reflect identity suppression or partner-based discouragement.", "escalation": "Moderate" }, { "id": "economic_control_001", "name": "Self-Denial Framed as Budgeting", "trigger_keywords": ["we can’t afford", "not in the budget", "no money for that"], "concern": "Covert economic control", "follow_up_therapist": "Has there ever been something they wanted to spend money on that you didn’t think you could afford?", "follow_up_cop": "Who decides what money gets spent on?", "insight": "When financial limitations are selectively applied to personal growth, it's often a form of control.", "escalation": "Moderate" }, { "id": "control_checkins_001", "name": "Monitoring & Check-ins", "trigger_keywords": ["have to check in", "need to be home by", "text when I get there"], "concern": "Surveillance / conditional autonomy", "follow_up_therapist": "What happens if you're late or forget to check in?", "follow_up_cop": "What happens if you don’t check in or come home late?", "insight": "Frequent required check-ins can signal coercive oversight or fear-based compliance.", "escalation": "High" }, { "id": "lethal_intimidation_001", "name": "Excessive Weapon Presence or Intimidation", "trigger_keywords": [ "guns in the house", "keeps a knife on him", "built his own gun", "gun isn’t locked", "open carry at home", "he always wears his knife", "refused to put guns in a safe", "too many weapons", "it makes me nervous" ], "concern": "Implied threat or coercive intimidation via weapon access", "follow_up_therapist": "How do you feel about the weapons being kept around — is that something you’re okay with?", "follow_up_cop": "Has there ever been a time where the presence of those weapons made you feel unsafe or changed how you responded in an argument?", "insight": "Unsafely stored or emotionally charged weapon presence can signal power imbalances, intimidation, and elevated risk of harm — especially when one partner is uncomfortable but compliance continues.", "escalation": "High" }, { "id": "digital_control_001", "name": "Digital Control via Shared or Monitored Social Media", "trigger_keywords": [ "we have a joint facebook", "shared account", "they manage our social media", "he doesn’t let me post", "i’m not allowed on social media", "we don’t really use social media" ], "concern": "Digital surveillance or identity suppression", "follow_up_therapist": "Was the joint account something you both wanted — or more their idea?", "follow_up_cop": "Have you ever felt like you couldn’t use social media freely or had to get permission before posting?", "insight": "Joint or controlled online accounts often signal deeper patterns of digital surveillance, identity suppression, or reputational control.", "escalation": "Moderate" }, { "id": "fawning_behavior_001", "name": "Hyper-Attunement to Partner’s Preferences", "trigger_keywords": [ "he doesn’t like when i", "she prefers i don’t", "i try not to upset them", "he’d hate that", "i just avoid it", "he gets upset when" ], "concern": "Chronic fear-based adjustment or internalized control", "follow_up_therapist": "What do you think would happen if you did it anyway?", "follow_up_cop": "Have you ever changed plans or avoided doing something because you didn’t want to upset them?", "insight": "Hyper-attunement to a partner’s preferences often reveals chronic behavioral conditioning rooted in fear, not genuine compromise.", "escalation": "Moderate" }, { "id": "minimizing_behavior_001", "name": "Minimizing or Defending the Abuser’s Behavior", "trigger_keywords": [ "he’s not abusive", "she didn’t mean to", "he just has a temper", "it’s not that bad", "he was just drunk", "she had a rough childhood", "it’s not like he hits me" ], "concern": "Normalization or justification of harm", "follow_up_therapist": "It sounds like you’re trying to make sense of their behavior — what part of you still feels unsure about how to name it?", "follow_up_cop": "Have you ever felt scared even if they didn’t physically hurt you?", "insight": "Minimizing or justifying harm without prompting signals grooming, normalization, or an internalized need to protect the abuser’s image.", "escalation": "High" } ] danger_questions = [ { "id": "da_1", "question": "Has the physical violence increased in frequency or severity?", "tags": ["threat", "control"], "follow_ups": [ "What triggered the most recent incident?", "What has changed since the first time it happened?" ] }, { "id": "da_2", "question": "Has your partner ever used a weapon against you or threatened you with one?", "tags": ["threat", "lethal_intimidation_001"], "follow_ups": [ "Where are the weapons usually kept?", "Has the presence of those weapons ever changed how you responded in an argument?" ] }, { "id": "da_3", "question": "Does your partner try to control most of your daily activities?", "tags": ["control", "monitoring"], "follow_ups": [ "Can you describe a time they told you not to do something?", "What happens if you don’t follow their preferences?" ] }, { "id": "da_4", "question": "Is your partner constantly or violently jealous?", "tags": ["projection", "insults", "control"], "follow_ups": [ "How do they respond when you talk to friends or coworkers?", "Have they accused you of cheating or lying without reason?" ] }, { "id": "da_5", "question": "Have you left your partner after living together and then returned?", "tags": ["recovery phase", "trauma bond", "guilt tripping"], "follow_ups": [ "What made you leave the first time?", "What made you go back?" ] }, { "id": "da_6", "question": "Has your partner ever threatened to kill you or themselves?", "tags": ["threat", "suicidal threat", "control"], "follow_ups": [ "How did you respond when they said that?", "Have they made this kind of threat more than once?" ] }, { "id": "da_7", "question": "Does your partner frequently put you down or humiliate you?", "tags": ["insults", "dismissiveness", "gaslighting"], "follow_ups": [ "Can you remember something they said that stuck with you?", "How do you usually respond when that happens?" ] }, { "id": "da_8", "question": "Do you feel afraid to disagree with your partner?", "tags": ["control", "dismissiveness", "emotional threat"], "follow_ups": [ "What do you think might happen if you did?", "Have you ever avoided speaking up to keep the peace?" ] }, { "id": "da_9", "question": "Does your partner follow or stalk you, or monitor your movements?", "tags": ["control", "digital control", "monitoring"], "follow_ups": [ "How do they keep track of where you are?", "Do you ever feel like you’re being watched or tracked?" ] }, { "id": "da_10", "question": "Has your partner ever forced or pressured you into sexual activity?", "tags": ["control", "threat", "guilt tripping"], "follow_ups": [ "Do you feel like you could say no safely?", "How do they usually respond when you aren’t in the mood?" ] }, { "id": "da_11", "question": "Does your partner isolate you from friends or family?", "tags": ["control", "digital control", "identity erosion"], "follow_ups": [ "Has anyone expressed concern about your relationship?", "Do you feel like you can talk to others freely?" ] }, { "id": "da_12", "question": "Do you rely on your partner for transportation, money, or housing?", "tags": ["economic control", "access restriction"], "follow_ups": [ "What would happen if you needed to leave suddenly?", "Do you have access to your own money or bank account?" ] }, { "id": "da_13", "question": "Has your partner ever harmed or threatened your pets?", "tags": ["threat", "emotional threat"], "follow_ups": [ "What happened when they did that?", "Did it change how you behaved afterward?" ] }, { "id": "da_14", "question": "Has your partner ever destroyed your property or personal items?", "tags": ["control", "threat", "emotional threat"], "follow_ups": [ "Do they ever break or throw things during arguments?", "How do you usually respond when they destroy something?" ] }, { "id": "da_15", "question": "Have you ever needed medical attention because of something your partner did?", "tags": ["threat", "escalation risk"], "follow_ups": [ "Did anyone help you at the time?", "Was it reported to anyone?" ] } ] # Analysis function def analyze_input(text, role): role_key = "therapist" if role == "Therapist" else "cop" input_text = text.lower() results = [] for pattern in patterns: if any(keyword in input_text for keyword in pattern["trigger_keywords"]): results.append( f"🔍 Pattern Detected: {pattern['name']}\n" f"Concern: {pattern['concern']}\n" f"Follow-Up Question: {pattern[f'follow_up_{role_key}']}\n" f"Insight: {pattern['insight']}\n" f"Escalation Risk: {pattern['escalation']}\n" ) if not results: return "No clear abuse pattern detected. Continue listening for contradictions, self-blame, or fear-based justifications." return "\n\n".join(results) # ——— Gradio Danger Assessment Wizard ——————————————————————————————————————— def danger_assessment_wizard(): with gr.Blocks() as demo: gr.Markdown("## 🔍 Danger Assessment Interview") gr.Markdown("Answer each question honestly. Follow-up questions will appear if you answer 'Yes'.") yes_responses = [] followup_textboxes = [] for dq in danger_questions: gr.Markdown(f"**{dq['question']}**") answer = gr.Radio(["Yes", "No"], label="Your Answer", value=None) yes_responses.append(answer) fups = [] for fup in dq["follow_ups"]: box = gr.Textbox(label=f"Follow-up: {fup}", visible=False) fups.append(box) followup_textboxes.append(box) def toggle_visibility(ans, *args): return [gr.update(visible=(ans == "Yes")) for _ in args] answer.change( toggle_visibility, inputs=[answer] + fups, outputs=fups ) submit = gr.Button("Submit Responses") output = gr.Textbox(label="Summary / Next Step", lines=5) def summarize(*args): yes_count = sum([1 for a in args[:len(yes_responses)] if a == "Yes"]) return f"✅ You answered 'Yes' to {yes_count} danger indicators. Follow-up responses captured for risk review." submit.click(fn=summarize, inputs=yes_responses + followup_textboxes, outputs=output) return demo # ——— Launch the Danger Wizard ———————————————————————————————————————————— if __name__ == "__main__": danger_assessment_wizard().launch() # Gradio UI gr.Interface( fn=analyze_input, inputs=[ gr.Textbox(lines=4, label="What did the person say?"), gr.Radio(["Therapist", "Law Enforcement"], label="Your Role") ], outputs="text", title="DV Pattern Recognition Tool (Prototype)", description="Enter a client or witness quote. The tool flags DV-related behavioral cues and suggests follow-up questions based on your role.")