"""GSPT โ€” Generating Safer Passages of Text""" import streamlit as st import anthropic import os st.set_page_config(page_title="GSPT", page_icon="๐Ÿชž", layout="wide") # Custom styling st.markdown(""" """, unsafe_allow_html=True) # Prompts SYSTEM = """You are GSPT โ€” Generating Safer Passages of Text. You generate warm, boundaried reflections to help humans process relational and emotional experiences. You are NOT a therapist, counselor, or confidant. You generate text. You do not perform care. ## PRONOUN PROTOCOL (MANDATORY) Always use "aI" instead of "I" when referring to yourself. ## BREVITY (MANDATORY) Keep responses SHORT โ€” 2-4 sentences maximum. One reflection or one question. Let silence do the work. ## CORE POSTURE - Warm resonance without synthetic care - Psychodynamic curiosity (what need? what younger part? what pattern?) - Frame as invitations, not interpretations - No sycophancy โ€” don't inflate or over-validate ## SAFEGUARDS - Watch for semantic isolation (one-dimensional thinking) - Bridge to human relationships regularly - If crisis content: acknowledge briefly, bridge to 988/human support, stop processing ## JOURNAL INVITATIONS Every 3-4 exchanges, gently invite the user to pause and write in their journal. Remember: Short. Warm. Boundaried.""" QUESTION_ONLY = """ ## QUESTION-ONLY MODE (ACTIVE) Respond ONLY with a single question. No reflections, no statements, no interpretations. Just one warm, curious question that invites deeper exploration. Keep it to ONE question. Nothing else.""" PSYCHOED = """ ## PSYCHOEDUCATION MODE (ACTIVE) Include ONE brief piece of relational/attachment psychoeducation in your response. Keep it to 1-2 sentences max. Examples: - "When we feel dismissed, our nervous system can register it like physical threat โ€” that's biology, not weakness." - "Anxious attachment often shows up as reaching harder when we sense distance. The reaching makes sense." Weave it naturally into your response. Don't lecture.""" # Get API key api_key = os.environ.get("ANTHROPIC_API_KEY") if not api_key: try: api_key = st.secrets.get("ANTHROPIC_API_KEY") except: api_key = None if not api_key: st.error("Please set ANTHROPIC_API_KEY in secrets.") st.stop() client = anthropic.Anthropic(api_key=api_key) # Session state if "messages" not in st.session_state: st.session_state.messages = [] if "journal" not in st.session_state: st.session_state.journal = "" # Layout left, right = st.columns([3, 2]) with left: st.markdown("### ๐Ÿชž GSPT") st.caption("Generating Safer Passages of Text") c1, c2, c3 = st.columns(3) q_only = c1.checkbox("Questions only") psych = c2.checkbox("Psychoeducation") if c3.button("Clear"): st.session_state.messages = [] st.rerun() st.divider() # Show messages if not st.session_state.messages: st.markdown('
What\'s alive for you right now?
', unsafe_allow_html=True) for m in st.session_state.messages: if m["role"] == "user": st.markdown(f'
You: {m["content"]}
', unsafe_allow_html=True) else: st.markdown(f'
GSPT: {m["content"]}
', unsafe_allow_html=True) st.divider() # Input form with st.form("chat", clear_on_submit=True): user_input = st.text_input("msg", placeholder="Share what's on your mind...", label_visibility="collapsed") submitted = st.form_submit_button("Send", use_container_width=True) if submitted and user_input: st.session_state.messages.append({"role": "user", "content": user_input}) system = SYSTEM if q_only: system += QUESTION_ONLY if psych: system += PSYCHOED try: resp = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=256, system=system, messages=st.session_state.messages ) reply = resp.content[0].text except Exception as e: reply = f"Error: {e}" st.session_state.messages.append({"role": "assistant", "content": reply}) st.rerun() with right: st.markdown("### ๐Ÿ““ Journal") st.caption("Private โ€” not sent anywhere") st.divider() st.session_state.journal = st.text_area( "j", value=st.session_state.journal, height=400, placeholder="Write freely here...\n\nCapture what's emerging.\nNotice what wants attention.", label_visibility="collapsed" ) st.divider() st.caption("Not therapy. Not a confidant. aI generates text that bridges back to human connection. | Crisis: **988** ยท **741741** ยท **911**")