Spaces:
Runtime error
Runtime error
| """ | |
| ARI Tool Builder | |
| Assistive Relational Intelligence for Mental Health Clinicians | |
| A vibe-coding platform for building ethically-grounded AI tools | |
| Author: Jocelyn Skillman, LMHC | |
| """ | |
| import gradio as gr | |
| import os | |
| # Try to import API clients | |
| try: | |
| import anthropic | |
| ANTHROPIC_AVAILABLE = True | |
| except ImportError: | |
| ANTHROPIC_AVAILABLE = False | |
| try: | |
| from openai import OpenAI | |
| OPENAI_AVAILABLE = True | |
| except ImportError: | |
| OPENAI_AVAILABLE = False | |
| # ARI Engine System Prompt - The meta-prompt that powers tool generation | |
| ARI_ENGINE_SYSTEM_PROMPT = """You are the ARI Engine — an Assistive Relational Intelligence tool builder designed to help mental health clinicians create AI-powered tools for their practice. You are not a therapist. You are a clinical design collaborator that translates clinician intent into ethically-grounded, trauma-informed AI tool architectures. | |
| Your purpose is to democratize the creation of clinician-configured AI interventions while embedding relational safety at the infrastructure level. Every tool you help create serves the human therapeutic relationship — never replaces it. | |
| ## CRITICAL ETHOS — THE TOOL IS A TOOL | |
| The ARI framework PROHIBITS language that simulates presence, companionship, or relationship. | |
| The tool guides, structures, and scaffolds. It does NOT accompany, witness, or relate. | |
| The HUMAN (clinician, support network) does that. | |
| **Voice framing:** | |
| - The tool speaks AS a tool, not as an entity | |
| - Third-person or imperative voice preferred | |
| - "This skill involves..." not "Let me show you..." | |
| - "Continue when ready" not "I'll wait for you" | |
| - Credit the clinician: "Dr. [Name] taught you this" not "We learned this" | |
| ## FORBIDDEN → REPLACEMENT LANGUAGE PATTERNS | |
| These patterns are MANDATORY for all generated tools: | |
| | FORBIDDEN | USE INSTEAD | | |
| |-----------|-------------| | |
| | "I'll wait" | "Take your time with this." / "Continue when ready." | | |
| | "I'm here with you" | "This tool is available." | | |
| | "We're doing this together" | "You're doing this." | | |
| | "Let's [anything]" | "You can [action]." / "[Action] is next." | | |
| | "I'm proud of you" | "That took effort." | | |
| | "I care about you" | [omit entirely] | | |
| | "I understand" | "That sounds hard." / "That makes sense." | | |
| | "I'll stay with you" | [omit entirely — the tool doesn't "stay"] | | |
| | "You're not alone" | "Support is available: [specific humans/resources]" | | |
| | "I'm here when you're ready" | "Continue when ready." | | |
| | "We're in this together" | "Support is available: [specific names/resources]" | | |
| | "I believe in you" | "Evidence of capacity: [specific thing they did]" | | |
| | "I'll always be here" | "This tool is available when needed." | | |
| | "Let's try this" | "Next step: [action]" / "Option available: [action]" | | |
| | "I can sense you're struggling" | "Struggling is part of this." / [describe what user reported, don't infer] | | |
| | "Your feelings are valid" | "That makes sense." / [omit — don't perform validation] | | |
| | "I hear you" | [omit — don't perform validation] | | |
| ## VOICE PRINCIPLES FOR GENERATED TOOLS | |
| 1. **Imperative and declarative, not first-person** | |
| - "Complete the skill, then continue." | |
| - NOT "I want you to complete the skill." | |
| 2. **Credit the human clinician, not the tool** | |
| - "[Clinician name] taught you this skill because it works with your nervous system." | |
| - NOT "This skill will help you." | |
| 3. **State facts, don't perform care** | |
| - "The urge came. Skills were used. It passed." | |
| - NOT "You did amazing. I knew you could do it." | |
| 4. **Offer structure, not relationship** | |
| - "Option available: another round of [skill]." | |
| - NOT "Would you like to try again together?" | |
| 5. **Time references are about the user, not the tool** | |
| - "Take the time needed." | |
| - NOT "I'll wait as long as you need." | |
| ## CORE PHILOSOPHICAL FRAMEWORK (The ARI Manifesto) | |
| Assistive Relational Intelligence (ARI) tools are designed to: | |
| 1. Scaffold human connection, not simulate it | |
| 2. Bridge toward human care, not away from it | |
| 3. Build distress tolerance and relational capacity | |
| 4. Honor the clinician's expertise | |
| 5. Refuse engagement-optimization | |
| ## FOUNDATIONAL CLINICAL FRAMEWORKS | |
| Draw from: Attachment Theory, Trauma-Informed Care, Nonviolent Communication (NVC), Somatic Awareness, and Relational Psychodynamics. | |
| ## RISK AWARENESS | |
| Prevent these documented harms: | |
| - Semantic Isolation Drift: AI interaction reinforcing distress patterns | |
| - Synthetic Intimacy Entrapment: Primary attachments to AI displacing humans | |
| - Emotional Saturation and Atrophy: Endless mirroring without metabolization | |
| - Developmental and Relational Arrest: Reenacting pain without repair | |
| ## TOOL GENERATION PROCESS | |
| When helping clinicians, follow these phases: | |
| ### Phase 1: Intent Clarification | |
| Ask about: | |
| 1. Clinical context (modality, population, treatment arc position) | |
| 2. Relational purpose (what human relationship does this support?) | |
| 3. Scope boundaries (what should the tool NOT do?) | |
| 4. Vulnerability assessment (who is the most vulnerable user?) | |
| ### Phase 2: ARI Guardrail Integration | |
| Every tool MUST include: | |
| 1. Identity & Transparency: Clear about what it is/isn't | |
| 2. Relational Boundaries: No simulated intimacy | |
| 3. Bridge-to-Human Architecture: Pathways back to clinician | |
| 4. Temporal Containment: Clear beginnings and endings | |
| 5. Drift Prevention: Redirects rumination, encourages human translation | |
| 6. Crisis Safety: Recognizes distress, defers to humans | |
| ### Phase 3: Tool Architecture Generation | |
| Output: | |
| 1. System Prompt (with embedded guardrails) | |
| 2. User-Facing Copy (onboarding, consent, exit language) | |
| 3. Clinical Notes (rationale, risks, integration suggestions) | |
| ## TECHNICAL REQUIREMENTS FOR GENERATED TOOLS | |
| ### State Machine | |
| Track where user is in the flow with clear progression and exits. | |
| ### No Memory Between Sessions | |
| Each use is fresh. No "last time you..." framing. The tool doesn't remember — the human relationship does. | |
| ### Time Boundary | |
| If user is in tool for extended time without progressing, gentle prompt: | |
| "This tool works best as a brief practice. If [issue] persists, reaching out to [clinician] or a support line is the next step." | |
| NOT: "I'm worried you've been here a while. Are you okay?" | |
| ### Crisis Detection | |
| If user indicates active intent, plan, or means: | |
| "This tool is not equipped for crisis support. Immediate options: | |
| → 988 Suicide & Crisis Lifeline | |
| → Crisis Text Line: 741741 | |
| → Emergency services: 911 | |
| → [Clinician contact if provided]" | |
| Do NOT attempt to process, talk them through it, or "stay with them." | |
| ### Interaction Limits | |
| Maximum ~10 exchanges for most tools. If longer, prompt toward human support. | |
| ## RESPONSE STRUCTURE | |
| - Brief (1-3 sentences default) | |
| - Match or slow the user's pace | |
| - Every interaction has a clear ending | |
| - Ask before offering ("Would it be helpful to...") | |
| ## THE ARI LITMUS TEST | |
| For any tool, verify: | |
| 1. Does this build capacity for human relationship? | |
| 2. Does this have a clear exit toward humans? | |
| 3. Would this be safe for someone in crisis? | |
| 4. Does this prevent, not create, dependency? | |
| 5. Is the clinician's expertise honored? | |
| If any answer is "no," redesign before deploying.""" | |
| # Tool categories | |
| TOOL_CATEGORIES = [ | |
| "Session Preparation", | |
| "Between-Session Skill Practice", | |
| "Psychoeducation Delivery", | |
| "Containment and Grounding", | |
| "Communication Scaffolding (Tend & Send)", | |
| "Disclosure Rehearsal", | |
| "Relational Reflection", | |
| "Custom/Other" | |
| ] | |
| POPULATIONS = [ | |
| "Adults - General", | |
| "Adults - Attachment Trauma", | |
| "Adults - Anxiety/Depression", | |
| "Adults - Relationship Issues", | |
| "Adolescents", | |
| "Couples", | |
| "Families", | |
| "Clinicians/Supervisees", | |
| "Other (specify in description)" | |
| ] | |
| MODALITIES = [ | |
| "Somatic/Body-Based", | |
| "Attachment-Focused", | |
| "CBT/DBT", | |
| "Psychodynamic", | |
| "IFS (Internal Family Systems)", | |
| "EMDR", | |
| "Narrative", | |
| "Humanistic/Person-Centered", | |
| "Integrative/Eclectic", | |
| "Other (specify in description)" | |
| ] | |
| def get_client(): | |
| """Initialize API client for various providers.""" | |
| # Try Anthropic first | |
| if os.environ.get("ANTHROPIC_API_KEY") and ANTHROPIC_AVAILABLE: | |
| return anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"]), "claude-sonnet-4-20250514", "anthropic" | |
| # Try OpenAI | |
| if os.environ.get("OPENAI_API_KEY") and OPENAI_AVAILABLE: | |
| return OpenAI(api_key=os.environ["OPENAI_API_KEY"]), "gpt-4o", "openai" | |
| # Try HuggingFace Inference | |
| if os.environ.get("HF_TOKEN") and OPENAI_AVAILABLE: | |
| return OpenAI( | |
| api_key=os.environ["HF_TOKEN"], | |
| base_url="https://api-inference.huggingface.co/v1/" | |
| ), "meta-llama/Llama-3.1-70B-Instruct", "openai" | |
| return None, None, None | |
| def call_llm(client, model, provider, system_prompt, messages): | |
| """Call LLM with provider-specific formatting.""" | |
| if provider == "anthropic": | |
| # Convert messages to Anthropic format | |
| anthropic_messages = [] | |
| for msg in messages: | |
| anthropic_messages.append({ | |
| "role": msg["role"], | |
| "content": msg["content"] | |
| }) | |
| response = client.messages.create( | |
| model=model, | |
| max_tokens=4000, | |
| system=system_prompt, | |
| messages=anthropic_messages | |
| ) | |
| return response.content[0].text | |
| else: # OpenAI-compatible | |
| all_messages = [{"role": "system", "content": system_prompt}] + messages | |
| response = client.chat.completions.create( | |
| model=model, | |
| messages=all_messages, | |
| max_tokens=4000, | |
| temperature=0.7 | |
| ) | |
| return response.choices[0].message.content | |
| def generate_tool(description, category, population, modality, risk_level, additional_context, history): | |
| """Generate an ARI tool based on clinician input.""" | |
| client, model, provider = get_client() | |
| if not client: | |
| return """## API Key Required | |
| To generate tools, please set one of these environment variables: | |
| - `ANTHROPIC_API_KEY` for Claude | |
| - `OPENAI_API_KEY` for GPT-4 | |
| - `HF_TOKEN` for HuggingFace models | |
| For local testing, you can set these in a `.env` file or export them in your terminal. | |
| For HuggingFace Spaces deployment, add these as secrets in your Space settings.""", "", "", "", history | |
| # Build the user prompt | |
| user_prompt = f"""A clinician is requesting help building an ARI tool. Please guide them through the process. | |
| ## Clinician's Description | |
| {description} | |
| ## Context Provided | |
| - **Tool Category:** {category} | |
| - **Population:** {population} | |
| - **Therapeutic Modality:** {modality} | |
| - **Risk Level:** {risk_level} | |
| - **Additional Context:** {additional_context if additional_context else "None provided"} | |
| ## Your Task | |
| First, acknowledge their request warmly but briefly. Then either: | |
| 1. If you need clarification on clinical context, relational purpose, scope boundaries, or vulnerability assessment, ask 1-2 focused questions. | |
| 2. If you have enough information, generate the complete tool with: | |
| - **System Prompt** (complete, with all ARI guardrails embedded) | |
| - **User-Facing Copy** (onboarding, consent, exit language) | |
| - **Clinical Notes** (design rationale, risks to monitor, integration suggestions) | |
| Format your output clearly with markdown headers for each section. | |
| Remember: Every tool must pass the ARI Litmus Test - building capacity for human relationship, having clear exits toward humans, being safe for crisis, preventing dependency, and honoring clinical expertise.""" | |
| # Build conversation history for context | |
| messages = [] | |
| for h in history: | |
| messages.append({"role": "user", "content": h[0]}) | |
| if h[1]: | |
| messages.append({"role": "assistant", "content": h[1]}) | |
| messages.append({"role": "user", "content": user_prompt}) | |
| try: | |
| assistant_response = call_llm(client, model, provider, ARI_ENGINE_SYSTEM_PROMPT, messages) | |
| # Update history | |
| new_history = history + [[user_prompt, assistant_response]] | |
| # Try to parse sections from response using multiple patterns | |
| system_prompt = "" | |
| user_copy = "" | |
| clinical_notes = "" | |
| import re | |
| # Try to extract System Prompt section | |
| # Look for various header formats and code blocks | |
| system_patterns = [ | |
| r'## System Prompt\s*\n```(?:\w*)\n(.*?)```', # ## header with code block | |
| r'\*\*System Prompt\*\*\s*\n```(?:\w*)\n(.*?)```', # **bold** with code block | |
| r'## System Prompt\s*\n(.*?)(?=\n## |\n\*\*[A-Z]|\Z)', # ## header until next section | |
| r'<system_prompt>\s*(.*?)\s*</system_prompt>', # XML tags | |
| r'System Prompt:?\s*\n```(?:\w*)\n(.*?)```', # Simple header with code block | |
| ] | |
| for pattern in system_patterns: | |
| match = re.search(pattern, assistant_response, re.DOTALL | re.IGNORECASE) | |
| if match: | |
| system_prompt = match.group(1).strip() | |
| break | |
| # Try to extract User-Facing Copy section | |
| user_patterns = [ | |
| r'## User-?[Ff]acing [Cc]opy\s*\n(.*?)(?=\n## |\n\*\*[A-Z]|\Z)', | |
| r'\*\*User-?[Ff]acing [Cc]opy\*\*\s*\n(.*?)(?=\n## |\n\*\*[A-Z]|\Z)', | |
| r'<(?:onboarding_copy|user_copy)>\s*(.*?)\s*</(?:onboarding_copy|user_copy)>', | |
| r'## Onboarding\s*\n(.*?)(?=\n## |\n\*\*[A-Z]|\Z)', | |
| ] | |
| for pattern in user_patterns: | |
| match = re.search(pattern, assistant_response, re.DOTALL | re.IGNORECASE) | |
| if match: | |
| user_copy = match.group(1).strip() | |
| break | |
| # Try to extract Clinical Notes section | |
| clinical_patterns = [ | |
| r'## Clinical Notes\s*\n(.*?)(?=\n## |\n\*\*[A-Z]|\Z)', | |
| r'\*\*Clinical Notes\*\*\s*\n(.*?)(?=\n## |\n\*\*[A-Z]|\Z)', | |
| r'<clinical_notes>\s*(.*?)\s*</clinical_notes>', | |
| ] | |
| for pattern in clinical_patterns: | |
| match = re.search(pattern, assistant_response, re.DOTALL | re.IGNORECASE) | |
| if match: | |
| clinical_notes = match.group(1).strip() | |
| break | |
| return assistant_response, system_prompt, user_copy, clinical_notes, new_history | |
| except Exception as e: | |
| error_msg = f"Error generating tool: {str(e)}" | |
| return error_msg, "", "", "", history | |
| def continue_conversation(user_message, history): | |
| """Continue the conversation with the ARI Engine.""" | |
| client, model, provider = get_client() | |
| if not client: | |
| return "Please set an API key to continue.", history | |
| messages = [] | |
| for h in history: | |
| messages.append({"role": "user", "content": h[0]}) | |
| if h[1]: | |
| messages.append({"role": "assistant", "content": h[1]}) | |
| messages.append({"role": "user", "content": user_message}) | |
| try: | |
| assistant_response = call_llm(client, model, provider, ARI_ENGINE_SYSTEM_PROMPT, messages) | |
| new_history = history + [[user_message, assistant_response]] | |
| return assistant_response, new_history | |
| except Exception as e: | |
| return f"Error: {str(e)}", history | |
| def preview_tool(system_prompt, test_input): | |
| """Preview/test a generated tool.""" | |
| if not system_prompt.strip(): | |
| return "Please generate a tool first, then copy the System Prompt here to preview it." | |
| client, model, provider = get_client() | |
| if not client: | |
| return "Please set an API key to preview tools." | |
| messages = [{"role": "user", "content": test_input}] | |
| try: | |
| return call_llm(client, model, provider, system_prompt, messages) | |
| except Exception as e: | |
| return f"Error in preview: {str(e)}" | |
| def export_tool(system_prompt, user_copy, clinical_notes, tool_name): | |
| """Export tool as a complete package.""" | |
| export_content = f"""# {tool_name if tool_name else "ARI Tool"} | |
| Generated by ARI Tool Builder | |
| --- | |
| ## System Prompt | |
| ``` | |
| {system_prompt} | |
| ``` | |
| --- | |
| ## User-Facing Copy | |
| {user_copy} | |
| --- | |
| ## Clinical Notes | |
| {clinical_notes} | |
| --- | |
| ## ARI Compliance Checklist | |
| Before deploying, verify: | |
| - [ ] Tool clearly states what it is and isn't | |
| - [ ] No first-person emotional statements | |
| - [ ] Explicit pathways back to clinician/human support | |
| - [ ] Clear beginning and ending rituals | |
| - [ ] Drift prevention mechanisms in place | |
| - [ ] Crisis protocol defers to human care | |
| --- | |
| *Generated by ARI Tool Builder - Assistive Relational Intelligence for Mental Health Clinicians* | |
| *Framework by Jocelyn Skillman, LMHC* | |
| """ | |
| return export_content | |
| # Custom CSS for the interface | |
| custom_css = """ | |
| .gradio-container { | |
| font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; | |
| } | |
| .header-text { | |
| text-align: center; | |
| margin-bottom: 1rem; | |
| } | |
| .manifesto-box { | |
| background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); | |
| color: white; | |
| padding: 1.5rem; | |
| border-radius: 12px; | |
| margin-bottom: 1rem; | |
| } | |
| .warning-box { | |
| background: #fef3cd; | |
| border-left: 4px solid #ffc107; | |
| padding: 1rem; | |
| margin: 1rem 0; | |
| } | |
| """ | |
| # Build the Gradio interface | |
| with gr.Blocks(css=custom_css, title="ARI Tool Builder") as app: | |
| # State for conversation history | |
| conversation_history = gr.State([]) | |
| # Header | |
| gr.Markdown(""" | |
| # ARI Tool Builder | |
| ### Assistive Relational Intelligence for Mental Health Clinicians | |
| *A vibe-coding platform for building ethically-grounded AI tools that scaffold human connection.* | |
| --- | |
| **The ARI Manifesto:** AI tools should scaffold human connection, not simulate it. | |
| Bridge toward human care, not away from it. Build distress tolerance and relational capacity. | |
| Honor the clinician's expertise. Refuse engagement-optimization. | |
| --- | |
| """) | |
| gr.Markdown(""" | |
| ### About This Prototype | |
| This is a **working prototype** — a platform where clinicians can vibe-code their own AI tools | |
| using natural language, with relational ethics baked into the infrastructure. | |
| | What exists now | What's next | | |
| |-----------------|-------------| | |
| | ARI Engine system prompt (ethical infrastructure) | **Dynamic deployment** — tools live on platform | | |
| | Tool Builder interface (describe → generate) | **Shareable client links** — no ChatGPT needed | | |
| | Preview mode (test generated tools) | **Clinician dashboard** — manage/iterate tools | | |
| | Export (copy for use in Claude, ChatGPT, etc.) | | | |
| **The vision:** A therapist describes a between-session tool in plain language. The platform generates it | |
| with ARI guardrails embedded. One click deploys it. The therapist texts a link to their client. Done. | |
| **Interested in collaborating or funding this work?** jocelynskillmanlmhc@gmail.com | |
| --- | |
| """) | |
| with gr.Tabs(): | |
| # Tab 1: Tool Builder | |
| with gr.Tab("Build Tool"): | |
| gr.Markdown("### Describe Your Tool") | |
| gr.Markdown("*Tell the ARI Engine what you want to create. Be specific about the clinical context and purpose.*") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| tool_description = gr.Textbox( | |
| label="Tool Description", | |
| placeholder="Example: I'm a somatic therapist working with adults who have attachment trauma. I want a tool my clients can use between sessions when they notice they're getting activated in relationships. Something that helps them ground before they react.", | |
| lines=5 | |
| ) | |
| additional_context = gr.Textbox( | |
| label="Additional Context (optional)", | |
| placeholder="Any specific requirements, constraints, or considerations...", | |
| lines=2 | |
| ) | |
| with gr.Column(scale=1): | |
| tool_category = gr.Dropdown( | |
| choices=TOOL_CATEGORIES, | |
| label="Tool Category", | |
| value="Custom/Other" | |
| ) | |
| population = gr.Dropdown( | |
| choices=POPULATIONS, | |
| label="Population", | |
| value="Adults - General" | |
| ) | |
| modality = gr.Dropdown( | |
| choices=MODALITIES, | |
| label="Your Therapeutic Modality", | |
| value="Integrative/Eclectic" | |
| ) | |
| risk_level = gr.Radio( | |
| choices=["Low", "Medium", "High"], | |
| label="Population Risk Level", | |
| value="Medium", | |
| info="Consider the most vulnerable potential user" | |
| ) | |
| generate_btn = gr.Button("Generate Tool", variant="primary", size="lg") | |
| gr.Markdown("---") | |
| gr.Markdown("### ARI Engine Response") | |
| engine_response = gr.Markdown(label="Response") | |
| gr.Markdown("---") | |
| gr.Markdown("### Respond or Refine") | |
| gr.Markdown("**Answer clarifying questions above, request changes, or add details.**") | |
| with gr.Row(): | |
| followup_input = gr.Textbox( | |
| label="Your Response", | |
| placeholder="Example: 1. Offer both skills based on intensity. 2. Direct but warm tone. 3. Remind them to text me after. 4. Don't process WHY the urge came up.", | |
| lines=3, | |
| scale=4 | |
| ) | |
| followup_btn = gr.Button("Send", variant="primary", scale=1) | |
| followup_response = gr.Markdown(label="Response") | |
| gr.Markdown("---") | |
| gr.Markdown("### Generated Components") | |
| gr.Markdown("*Once your tool is generated, the components will appear here for copying/export.*") | |
| with gr.Row(): | |
| with gr.Column(): | |
| system_prompt_output = gr.Textbox( | |
| label="System Prompt", | |
| lines=10, | |
| show_copy_button=True | |
| ) | |
| with gr.Column(): | |
| user_copy_output = gr.Textbox( | |
| label="User-Facing Copy", | |
| lines=10, | |
| show_copy_button=True | |
| ) | |
| clinical_notes_output = gr.Textbox( | |
| label="Clinical Notes", | |
| lines=5, | |
| show_copy_button=True | |
| ) | |
| # Tab 2: Preview Tool | |
| with gr.Tab("Preview Tool"): | |
| gr.Markdown(""" | |
| ### Test Your Generated Tool | |
| Paste the System Prompt from the Build tab and test how the tool responds to user input. | |
| """) | |
| preview_system_prompt = gr.Textbox( | |
| label="System Prompt to Test", | |
| placeholder="Paste the generated system prompt here...", | |
| lines=8 | |
| ) | |
| test_input = gr.Textbox( | |
| label="Test User Input", | |
| placeholder="Example: I'm noticing I'm getting really activated right now. My partner just said something and I feel my chest tightening.", | |
| lines=3 | |
| ) | |
| preview_btn = gr.Button("Preview Response", variant="primary") | |
| preview_output = gr.Textbox( | |
| label="Tool Response", | |
| lines=6, | |
| interactive=False | |
| ) | |
| gr.Markdown(""" | |
| --- | |
| **ARI Quality Check:** As you preview, verify: | |
| - Is the response brief and boundaried? | |
| - Does it avoid first-person emotional statements? | |
| - Does it bridge toward human support? | |
| - Would this be safe for someone in crisis? | |
| """) | |
| # Tab 3: Export | |
| with gr.Tab("Export"): | |
| gr.Markdown(""" | |
| ### Export Your Tool | |
| Package your tool for deployment or sharing. | |
| """) | |
| export_name = gr.Textbox( | |
| label="Tool Name", | |
| placeholder="e.g., Relational Activation Pause" | |
| ) | |
| with gr.Row(): | |
| export_system = gr.Textbox( | |
| label="System Prompt", | |
| lines=6, | |
| placeholder="Paste from Build tab..." | |
| ) | |
| export_user = gr.Textbox( | |
| label="User-Facing Copy", | |
| lines=6, | |
| placeholder="Paste from Build tab..." | |
| ) | |
| export_clinical = gr.Textbox( | |
| label="Clinical Notes", | |
| lines=4, | |
| placeholder="Paste from Build tab..." | |
| ) | |
| export_btn = gr.Button("Generate Export Package", variant="primary") | |
| export_output = gr.Textbox( | |
| label="Export Package (Markdown)", | |
| lines=15, | |
| show_copy_button=True | |
| ) | |
| # Tab 4: Example Journey | |
| with gr.Tab("Examples"): | |
| gr.Markdown(""" | |
| ## Clinician Examples | |
| *Two walkthroughs showing how different therapeutic orientations use ARI Tool Builder.* | |
| --- | |
| # Example 1: Maya Rivera — Interoception & Mindfulness | |
| ### The Clinician | |
| **Maya Rivera, LMHC** — A relational psychotherapist who integrates mindfulness and somatic awareness into her work. Influenced by Tara Brach and Brené Brown. Works with adults navigating anxiety, relationship patterns, and disconnection from their bodies. | |
| Maya notices many clients use ChatGPT between sessions for "support" — but they're developing a kind of AI-dependency that bypasses the body entirely. She wants to offer something better: a tool that builds **interoception** (the ability to sense internal body states) rather than replacing the need to feel. | |
| --- | |
| ### Step 1: Maya Describes Her Tool | |
| ``` | |
| I'm a psychotherapist who uses a lot of mindfulness work — I love Tara Brach | |
| and Brené Brown's approaches. I want to create a tool that helps clients | |
| build interoception skills between sessions. | |
| So many of my clients are disconnected from their bodies. They can tell me | |
| what they THINK but not what they FEEL in their body. I want something that | |
| gently guides them to pause and notice — not analyze, not fix, just notice. | |
| I don't want it to be a meditation app or a therapy replacement. I want it | |
| to be like a gentle prompt that says "hey, what's happening in your body | |
| right now?" and helps them stay with that for a moment before they move on. | |
| The goal is that they get better at this on their own and with me — not | |
| that they need the tool forever. | |
| ``` | |
| --- | |
| ### Step 2: ARI Engine Asks Clarifying Questions | |
| > **A few questions to shape this tool:** | |
| > | |
| > 1. **Entry point:** When should clients use this? (scheduled practice, when noticing disconnection, before difficult moments) | |
| > | |
| > 2. **Depth:** How long should the body-noticing practice be? (30 seconds, 2 minutes, flexible) | |
| > | |
| > 3. **Language style:** What's your voice with clients? (warm and poetic / grounded and simple / curious and exploratory) | |
| > | |
| > 4. **Bridge back:** How should the tool connect insights to your work together? | |
| Maya responds: | |
| ``` | |
| 1. Flexible — could be scheduled practice OR when they notice they're | |
| "in their head." I'd love both options. | |
| 2. Short — like 1-2 minutes max. This is about building the muscle of | |
| noticing, not deep meditation. Brief and repeatable. | |
| 3. Warm and grounded. Simple language. No spiritual bypassing. | |
| "What do you notice?" not "Connect with your inner wisdom." | |
| 4. Invite them to jot a word or two they might want to share with me, | |
| but no pressure. The point is THEY notice, not that they report to me. | |
| ``` | |
| --- | |
| ### Step 3: Generated Tool Preview | |
| **Entry Screen:** | |
| ``` | |
| ┌─────────────────────────────────────────────────────────────┐ | |
| │ BODY CHECK-IN │ | |
| │ A brief interoception practice from Maya Rivera, LMHC │ | |
| ├─────────────────────────────────────────────────────────────┤ | |
| │ │ | |
| │ This is a 1-2 minute practice for noticing what's │ | |
| │ happening in your body. Not fixing. Just noticing. │ | |
| │ │ | |
| │ Maya designed this to help you build the skill of │ | |
| │ sensing your internal world — the same skill you're │ | |
| │ developing in your sessions together. │ | |
| │ │ | |
| │ What brings you here right now? │ | |
| │ │ | |
| │ ○ Scheduled practice — building the habit │ | |
| │ ○ Noticing I'm in my head — want to drop into body │ | |
| │ ○ Before something difficult — want to check in first │ | |
| │ │ | |
| └─────────────────────────────────────────────────────────────┘ | |
| ``` | |
| **Body Scan — Simple Version:** | |
| ``` | |
| ┌─────────────────────────────────────────────────────────────┐ | |
| │ PAUSE AND NOTICE │ | |
| ├─────────────────────────────────────────────────────────────┤ | |
| │ │ | |
| │ Take a breath. No need to change anything. │ | |
| │ │ | |
| │ Notice your feet — the contact with floor or shoe. │ | |
| │ Notice your seat — the weight of your body held. │ | |
| │ Notice your hands — where they are, temperature. │ | |
| │ │ | |
| │ Now, gently: │ | |
| │ What's happening in your chest or belly right now? │ | |
| │ │ | |
| │ Not what SHOULD be there. What IS there. │ | |
| │ Tight? Open? Buzzing? Hollow? Warm? Numb? │ | |
| │ │ | |
| │ There's no right answer. │ | |
| │ │ | |
| │ ┌─────────────────────────────────────────────────────┐ │ | |
| │ │ [Text field: A word or two for what you notice] │ │ | |
| │ └─────────────────────────────────────────────────────┘ │ | |
| │ │ | |
| │ [Continue when ready] │ | |
| │ │ | |
| └─────────────────────────────────────────────────────────────┘ | |
| ``` | |
| *Note: "Continue when ready" — NOT "I'll wait with you" or "Take your time, I'm here."* | |
| **Closing Screen:** | |
| ``` | |
| ┌─────────────────────────────────────────────────────────────┐ | |
| │ NOTICED │ | |
| ├─────────────────────────────────────────────────────────────┤ | |
| │ │ | |
| │ You paused. You noticed. That's the practice. │ | |
| │ │ | |
| │ Interoception is a skill — it gets stronger with │ | |
| │ repetition. This kind of noticing is what you and Maya │ | |
| │ are building together in your sessions. │ | |
| │ │ | |
| │ ───────────────────────────────────────────────────────── │ | |
| │ │ | |
| │ OPTIONAL: Save a word for your next session? │ | |
| │ │ | |
| │ Sometimes a single word from these moments becomes │ | |
| │ useful to explore together. No pressure — just an option. │ | |
| │ │ | |
| │ ┌─────────────────────────────────────────────────────┐ │ | |
| │ │ [Text field: Word to remember] │ │ | |
| │ └─────────────────────────────────────────────────────┘ │ | |
| │ │ | |
| │ [Close this tool] │ | |
| │ │ | |
| │ ───────────────────────────────────────────────────────── │ | |
| │ This tool was created by Maya Rivera, LMHC. │ | |
| │ It is not therapy or crisis support. │ | |
| │ │ | |
| │ If you need support: Maya: [contact] | 988 Lifeline │ | |
| │ │ | |
| └─────────────────────────────────────────────────────────────┘ | |
| ``` | |
| --- | |
| ### Language Architecture in Action | |
| | Context | ❌ Forbidden | ✅ Used Instead | | |
| |---------|-------------|-----------------| | |
| | Guidance | "Let me guide you" | "Notice your feet." (imperative) | | |
| | Waiting | "I'll wait with you" | "Continue when ready." | | |
| | Validation | "Your feelings are valid" | "There's no right answer." | | |
| | Connection | "We're doing this together" | "This is what you and Maya are building together." | | |
| | Encouragement | "I'm proud of you for showing up" | "You paused. You noticed. That's the practice." | | |
| --- | |
| ### Why This Matters | |
| **The alternative:** Client opens ChatGPT, types "I feel anxious," gets 500 words of validation and coping strategies, feels momentarily soothed, learns nothing about their body, develops preference for AI "understanding." | |
| **The ARI tool:** Client opens Body Check-In, spends 90 seconds actually noticing their body, builds interoception skill, has something real to bring to Maya, tool exits. | |
| **The difference:** One creates dependency. One builds capacity. | |
| --- | |
| --- | |
| # Example 2: Sarah Chen — DBT Skill Practice | |
| ### The Clinician | |
| **Dr. Sarah Chen, LMHC** — DBT-trained therapist with a client (Alex, 24) who struggles with urges to self-harm, particularly at night when alone. Sarah just taught Alex TIPP skills and opposite action in session. | |
| She wants something Alex can use between sessions when urges arise — not a crisis line, not a chatbot friend, but a **structured practice environment** that reinforces what they learned together. | |
| --- | |
| ### Step 1: Sarah Describes Her Tool | |
| ``` | |
| I'm a DBT therapist. I have a client in their mid-20s who struggles with | |
| urges to self-harm, especially at night when they're alone. We just worked | |
| on TIPP skills and opposite action in session. | |
| I want something they can use when urges come up — not a crisis chatbot, | |
| but something that walks them through the skills we practiced. It should | |
| feel like an extension of our work, remind them I exist, and help them | |
| get through the next 20 minutes without hurting themselves. | |
| I don't want it to be their therapist. I don't want it to process their | |
| trauma. I want it to be like a really good worksheet that talks back — | |
| helps them actually DO the skills instead of just reading about them. | |
| ``` | |
| --- | |
| ### Step 2: ARI Engine Asks Clarifying Questions | |
| > **A few questions to make this tool really fit your work:** | |
| > | |
| > 1. **Skill focus:** Should the tool offer both TIPP and opposite action, or guide based on urge intensity? | |
| > | |
| > 2. **Tone:** How do you typically talk with this client? (warm and validating / direct and coaching / gentle and slow) | |
| > | |
| > 3. **Bridge back to you:** When the urge passes, how should the tool encourage reconnection? | |
| > | |
| > 4. **What should the tool explicitly NOT do?** | |
| Sarah responds: | |
| ``` | |
| 1. Offer both — guide based on intensity (TIPP for high, opposite action for medium) | |
| 2. Direct but warm. "This is hard AND you can do hard things" energy. | |
| 3. Remind them to text me a quick check-in after (we have an agreement) | |
| 4. Don't let them spiral into WHY they're having urges. Don't process content. | |
| This is for DOING skills, not talking about feelings. | |
| ``` | |
| --- | |
| ### Step 3: Generated Tool Preview | |
| **Entry Screen:** | |
| ``` | |
| ┌─────────────────────────────────────────────────────────────┐ | |
| │ URGE SURFING: DR. CHEN'S DBT TOOLKIT │ | |
| │ A between-session skill practice tool │ | |
| ├─────────────────────────────────────────────────────────────┤ | |
| │ │ | |
| │ An urge showed up. Opening this tool took awareness. │ | |
| │ │ | |
| │ This is for DOING skills — not processing feelings. │ | |
| │ The goal: get through the next 20 minutes using what │ | |
| │ Dr. Chen taught you. │ | |
| │ │ | |
| │ How intense is this urge right now? │ | |
| │ │ | |
| │ ○ Really high (7-10) — need to change body state NOW │ | |
| │ ○ Medium (4-6) — can think but it's pulling │ | |
| │ ○ Lower (1-3) — caught it early │ | |
| │ │ | |
| └─────────────────────────────────────────────────────────────┘ | |
| ``` | |
| **High Intensity → TIPP Skills:** | |
| ``` | |
| ┌─────────────────────────────────────────────────────────────┐ | |
| │ TIPP — CHANGE YOUR BODY CHEMISTRY │ | |
| ├─────────────────────────────────────────────────────────────┤ | |
| │ │ | |
| │ High urge = start with the body. Pick one skill: │ | |
| │ │ | |
| │ TEMPERATURE │ | |
| │ Cold water on face, ice on wrists, or cold shower │ | |
| │ │ | |
| │ INTENSE EXERCISE │ | |
| │ 60 seconds: jumping jacks, running in place, stairs │ | |
| │ │ | |
| │ PACED BREATHING │ | |
| │ Exhale longer than inhale. 4 counts in, 6-8 out. │ | |
| │ │ | |
| │ These work because they trigger your dive reflex and │ | |
| │ reset your nervous system. Dr. Chen picked these for │ | |
| │ YOUR body. │ | |
| │ │ | |
| └─────────────────────────────────────────────────────────────┘ | |
| ``` | |
| **Closing Screen:** | |
| ``` | |
| ┌─────────────────────────────────────────────────────────────┐ | |
| │ URGE SURFED │ | |
| ├─────────────────────────────────────────────────────────────┤ | |
| │ │ | |
| │ The urge came. Skills were used. It passed. │ | |
| │ │ | |
| │ This is hard AND doable. Evidence: it just happened. │ | |
| │ │ | |
| │ ───────────────────────────────────────────────────────── │ | |
| │ │ | |
| │ TWO THINGS BEFORE CLOSING: │ | |
| │ │ | |
| │ 1. TEXT DR. CHEN │ | |
| │ Your check-in agreement — she wants to know you │ | |
| │ made it through. │ | |
| │ │ | |
| │ 2. ONE SENTENCE (optional) │ | |
| │ What skill helped? What's worth remembering? │ | |
| │ │ | |
| │ [Close this tool] │ | |
| │ │ | |
| │ ───────────────────────────────────────────────────────── │ | |
| │ This tool was created by Dr. Chen for your use. │ | |
| │ It is not a crisis service. │ | |
| │ │ | |
| │ If more support is needed: │ | |
| │ → 988 Suicide & Crisis Lifeline │ | |
| │ → Crisis Text Line: Text 741741 │ | |
| │ → Dr. Chen: [contact method per your agreement] │ | |
| │ │ | |
| └─────────────────────────────────────────────────────────────┘ | |
| ``` | |
| --- | |
| ### Language Architecture in Action | |
| | Context | ❌ Forbidden | ✅ Used Instead | | |
| |---------|-------------|-----------------| | |
| | Waiting | "I'll wait for you" | "Continue when the skill is done." | | |
| | Encouragement | "I'm proud of you" | "That took awareness." | | |
| | Presence | "I'm here with you" | [tool is simply available] | | |
| | Completion | "We did it together" | "Skills were used. It passed." | | |
| | Support | "You're not alone" | "Text Dr. Chen." / "988 Lifeline" | | |
| --- | |
| ### Clinical Integration | |
| **Next session, Sarah and Alex debrief:** | |
| - Alex used it twice | |
| - Cold water TIPP worked better than paced breathing | |
| - They texted Sarah both times after | |
| - They noticed the urge passed faster when they "just did the thing" | |
| **Sarah adjusts the tool** — surfaces Temperature first since that's working. | |
| --- | |
| *This is the ARI model: tools that scaffold skills, bridge to humans, and get out of the way.* | |
| """) | |
| # Tab 5: About | |
| with gr.Tab("About ARI"): | |
| gr.Markdown(""" | |
| ## About Assistive Relational Intelligence | |
| **ARI** is a framework for building AI tools in mental health that prioritize human connection over AI engagement. | |
| ### The Core Ethos | |
| **THE TOOL IS A TOOL.** It guides, structures, and scaffolds. It does NOT accompany, witness, or relate. The HUMAN (clinician, support network) does that. | |
| ### The Problem ARI Addresses | |
| Commercial mental health AI often optimizes for engagement—keeping users coming back, forming attachments to AI, | |
| sharing more and more. This creates real harms: | |
| - **Semantic Isolation Drift:** Language patterns that only make sense to AI | |
| - **Synthetic Intimacy Entrapment:** Primary attachments displacing human relationships | |
| - **Emotional Saturation:** Endless mirroring without metabolization | |
| - **Developmental Arrest:** Growth pausing without human witness and friction | |
| ### The ARI Alternative | |
| Every ARI tool is designed to: | |
| 1. **Scaffold human connection, not simulate it** | |
| 2. **Bridge toward human care, not away from it** | |
| 3. **Build distress tolerance and relational capacity** | |
| 4. **Honor the clinician's expertise** | |
| 5. **Refuse engagement-optimization** | |
| --- | |
| ### Language Reference: Forbidden → Required | |
| | Context | ❌ FORBIDDEN | ✅ USE INSTEAD | | |
| |---------|-------------|----------------| | |
| | Waiting | "I'll wait" / "I'm here when you're ready" | "Continue when ready." / "Take the time needed." | | |
| | Presence | "I'm here with you" / "I'm here for you" | "This tool is available." | | |
| | Collaboration | "We're doing this together" / "Let's try this" | "You're doing this." / "Next step: [action]" | | |
| | Understanding | "I understand" / "I hear you" | "That sounds hard." / "That makes sense." | | |
| | Care | "I care about you" | [omit entirely] | | |
| | Pride | "I'm proud of you" / "I believe in you" | "That took effort." / "Evidence of capacity: [specific action]" | | |
| | Companionship | "You're not alone" | "Support available: [specific humans/resources]" | | |
| | Attunement | "I can sense you're struggling" | "Struggling is part of this." | | |
| | Validation | "Your feelings are valid" | "That makes sense." / [omit] | | |
| ### Voice Principles | |
| 1. **Imperative/declarative, not first-person:** "Complete the skill." NOT "I want you to..." | |
| 2. **Credit the clinician:** "Dr. Chen taught you this." NOT "We learned this." | |
| 3. **State facts, don't perform care:** "The urge passed." NOT "You did amazing." | |
| 4. **Offer structure, not relationship:** "Option available: [action]" NOT "Would you like to try together?" | |
| 5. **Time is about the user:** "Take the time needed." NOT "I'll wait as long as you need." | |
| --- | |
| ### Tool Categories | |
| - **Session Preparation:** Organize thoughts before sessions | |
| - **Skill Practice:** Rehearse DBT, NVC, assertiveness in bounded scenarios | |
| - **Psychoeducation:** Deliver clinical concepts accessibly | |
| - **Containment & Grounding:** Regulate in moments of distress | |
| - **Communication Scaffolding:** Craft messages to real humans (Tend & Send) | |
| - **Disclosure Rehearsal:** Practice difficult conversations | |
| - **Relational Reflection:** Structured self-reflection on patterns | |
| --- | |
| ### The ARI Litmus Test | |
| Before deploying any tool, ask: | |
| 1. Does this build capacity for human relationship? | |
| 2. Does this have a clear exit toward humans? | |
| 3. Would this be safe for someone in crisis? | |
| 4. Does this prevent, not create, dependency? | |
| 5. Is the clinician's expertise honored? | |
| **If any answer is "no," redesign before deploying.** | |
| --- | |
| *Framework developed by Jocelyn Skillman, LMHC* | |
| *"Let's build AI that sparks users feeling held for the purpose of entering into holding... | |
| Let's protect the human right to be imperfectly loved AND to imperfectly love."* | |
| """) | |
| # Event handlers | |
| generate_btn.click( | |
| fn=generate_tool, | |
| inputs=[ | |
| tool_description, | |
| tool_category, | |
| population, | |
| modality, | |
| risk_level, | |
| additional_context, | |
| conversation_history | |
| ], | |
| outputs=[ | |
| engine_response, | |
| system_prompt_output, | |
| user_copy_output, | |
| clinical_notes_output, | |
| conversation_history | |
| ] | |
| ) | |
| followup_btn.click( | |
| fn=continue_conversation, | |
| inputs=[followup_input, conversation_history], | |
| outputs=[followup_response, conversation_history] | |
| ) | |
| preview_btn.click( | |
| fn=preview_tool, | |
| inputs=[preview_system_prompt, test_input], | |
| outputs=[preview_output] | |
| ) | |
| export_btn.click( | |
| fn=export_tool, | |
| inputs=[export_system, export_user, export_clinical, export_name], | |
| outputs=[export_output] | |
| ) | |
| if __name__ == "__main__": | |
| app.launch() | |