Spaces:
Sleeping
Sleeping
| 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.") |