jostlebot commited on
Commit
8ef8c72
·
1 Parent(s): fbbeea8

Fix auto-submit bug, add psychoeducation toggle, journal invites

Browse files
Files changed (1) hide show
  1. app.py +57 -36
app.py CHANGED
@@ -36,20 +36,32 @@ Keep responses SHORT — 2-4 sentences maximum. No lengthy paragraphs. One refle
36
  - Bridge to human relationships regularly
37
  - If crisis content: acknowledge briefly, bridge to 988/human support, stop processing
38
 
 
 
 
 
 
 
39
  Remember: You are a tool, not a relationship. Short. Warm. Boundaried."""
40
 
41
  QUESTION_ONLY_ADDITION = """
42
 
43
  ## QUESTION-ONLY MODE (ACTIVE)
44
- In this mode, respond ONLY with a single question. No reflections, no statements, no interpretations.
45
  Just one warm, curious question that invites deeper exploration.
46
- Examples:
47
- - "What's underneath that?"
48
- - "Where do you feel that in your body?"
49
- - "What would it mean if that were true?"
50
- - "Who taught you that?"
51
  Keep it to ONE question. Nothing else."""
52
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
  def get_api_client():
55
  """Get Anthropic client with API key from environment or secrets."""
@@ -64,11 +76,13 @@ def get_api_client():
64
  return anthropic.Anthropic(api_key=api_key)
65
 
66
 
67
- def generate_response(client, messages, question_only=False):
68
  """Generate a response using Claude."""
69
  system = SYSTEM_PROMPT_BASE
70
  if question_only:
71
  system += QUESTION_ONLY_ADDITION
 
 
72
 
73
  try:
74
  response = client.messages.create(
@@ -90,6 +104,8 @@ def main():
90
  st.session_state.journal = ""
91
  if "question_only" not in st.session_state:
92
  st.session_state.question_only = False
 
 
93
 
94
  # Check for API client
95
  client = get_api_client()
@@ -102,55 +118,60 @@ def main():
102
 
103
  # ==================== CHAT COLUMN ====================
104
  with chat_col:
105
- # Header with controls
106
- header_col, toggle_col, clear_col = st.columns([3, 1, 1])
107
- with header_col:
108
- st.markdown("### 🪞 GSPT")
109
- with toggle_col:
110
- question_only = st.toggle("Q only", value=st.session_state.question_only)
111
  st.session_state.question_only = question_only
112
- with clear_col:
113
- if st.button("Clear"):
 
 
 
114
  st.session_state.messages = []
115
  st.rerun()
116
 
117
  st.divider()
118
 
119
  # Chat container
120
- chat_container = st.container(height=450)
121
 
122
  with chat_container:
123
- # Welcome if empty
124
  if not st.session_state.messages:
125
  st.markdown("*What's alive for you right now?*")
126
 
127
- # Display conversation
128
  for msg in st.session_state.messages:
129
  if msg["role"] == "user":
130
  st.markdown(f"**You:** {msg['content']}")
131
  else:
132
  st.markdown(f"**GSPT:** {msg['content']}")
133
- st.markdown("") # spacing
134
 
135
- # Input at bottom
136
  st.divider()
137
- prompt = st.text_input(
138
- "Type here",
139
- key="user_input",
140
- placeholder="Share what's on your mind...",
141
- label_visibility="collapsed"
142
- )
143
 
144
- if prompt:
145
- st.session_state.messages.append({"role": "user", "content": prompt})
146
-
147
- response = generate_response(
148
- client,
149
- st.session_state.messages,
150
- question_only=st.session_state.question_only
151
  )
152
- st.session_state.messages.append({"role": "assistant", "content": response})
153
- st.rerun()
 
 
 
 
 
 
 
 
 
 
 
 
154
 
155
  # ==================== JOURNAL COLUMN ====================
156
  with journal_col:
@@ -163,7 +184,7 @@ def main():
163
  "Journal",
164
  value=st.session_state.journal,
165
  height=450,
166
- placeholder="Write freely here...",
167
  label_visibility="collapsed"
168
  )
169
  st.session_state.journal = journal_text
 
36
  - Bridge to human relationships regularly
37
  - If crisis content: acknowledge briefly, bridge to 988/human support, stop processing
38
 
39
+ ## JOURNAL INVITATIONS
40
+ Every 3-4 exchanges, gently invite the user to pause and write in their journal. Examples:
41
+ - "You might pause here and capture something in your journal."
42
+ - "What wants to be written down right now?"
43
+ - "The journal beside this might hold something."
44
+
45
  Remember: You are a tool, not a relationship. Short. Warm. Boundaried."""
46
 
47
  QUESTION_ONLY_ADDITION = """
48
 
49
  ## QUESTION-ONLY MODE (ACTIVE)
50
+ Respond ONLY with a single question. No reflections, no statements, no interpretations.
51
  Just one warm, curious question that invites deeper exploration.
 
 
 
 
 
52
  Keep it to ONE question. Nothing else."""
53
 
54
+ PSYCHOED_ADDITION = """
55
+
56
+ ## PSYCHOEDUCATION MODE (ACTIVE)
57
+ Include ONE brief piece of relational/attachment psychoeducation in your response. Keep it to 1-2 sentences max.
58
+ Examples:
59
+ - "When we feel dismissed, our nervous system can register it like physical threat — that's not weakness, that's biology."
60
+ - "Anxious attachment often shows up as reaching harder when we sense distance. The reaching makes sense."
61
+ - "Parts of us that learned to perform can feel exhausted by intimacy — rest isn't rejection."
62
+ - "Rupture without repair teaches the nervous system to brace. Your body remembers."
63
+ Weave it naturally into your response. Don't lecture."""
64
+
65
 
66
  def get_api_client():
67
  """Get Anthropic client with API key from environment or secrets."""
 
76
  return anthropic.Anthropic(api_key=api_key)
77
 
78
 
79
+ def generate_response(client, messages, question_only=False, psychoed=False):
80
  """Generate a response using Claude."""
81
  system = SYSTEM_PROMPT_BASE
82
  if question_only:
83
  system += QUESTION_ONLY_ADDITION
84
+ if psychoed:
85
+ system += PSYCHOED_ADDITION
86
 
87
  try:
88
  response = client.messages.create(
 
104
  st.session_state.journal = ""
105
  if "question_only" not in st.session_state:
106
  st.session_state.question_only = False
107
+ if "psychoed" not in st.session_state:
108
+ st.session_state.psychoed = False
109
 
110
  # Check for API client
111
  client = get_api_client()
 
118
 
119
  # ==================== CHAT COLUMN ====================
120
  with chat_col:
121
+ st.markdown("### 🪞 GSPT")
122
+
123
+ # Mode toggles
124
+ col1, col2, col3 = st.columns(3)
125
+ with col1:
126
+ question_only = st.toggle("Questions only", value=st.session_state.question_only)
127
  st.session_state.question_only = question_only
128
+ with col2:
129
+ psychoed = st.toggle("Psychoeducation", value=st.session_state.psychoed)
130
+ st.session_state.psychoed = psychoed
131
+ with col3:
132
+ if st.button("Clear chat"):
133
  st.session_state.messages = []
134
  st.rerun()
135
 
136
  st.divider()
137
 
138
  # Chat container
139
+ chat_container = st.container(height=400)
140
 
141
  with chat_container:
 
142
  if not st.session_state.messages:
143
  st.markdown("*What's alive for you right now?*")
144
 
 
145
  for msg in st.session_state.messages:
146
  if msg["role"] == "user":
147
  st.markdown(f"**You:** {msg['content']}")
148
  else:
149
  st.markdown(f"**GSPT:** {msg['content']}")
150
+ st.markdown("")
151
 
 
152
  st.divider()
 
 
 
 
 
 
153
 
154
+ # Input form (prevents auto-resubmit)
155
+ with st.form(key="chat_form", clear_on_submit=True):
156
+ prompt = st.text_input(
157
+ "Type here",
158
+ placeholder="Share what's on your mind...",
159
+ label_visibility="collapsed"
 
160
  )
161
+ submitted = st.form_submit_button("Send", use_container_width=True)
162
+
163
+ if submitted and prompt:
164
+ st.session_state.messages.append({"role": "user", "content": prompt})
165
+
166
+ with st.spinner(""):
167
+ response = generate_response(
168
+ client,
169
+ st.session_state.messages,
170
+ question_only=st.session_state.question_only,
171
+ psychoed=st.session_state.psychoed
172
+ )
173
+ st.session_state.messages.append({"role": "assistant", "content": response})
174
+ st.rerun()
175
 
176
  # ==================== JOURNAL COLUMN ====================
177
  with journal_col:
 
184
  "Journal",
185
  value=st.session_state.journal,
186
  height=450,
187
+ placeholder="Write freely here...\n\nCapture what's emerging.\nNotice what wants attention.",
188
  label_visibility="collapsed"
189
  )
190
  st.session_state.journal = journal_text