Spaces:
Sleeping
Sleeping
Add enhanced debrief mode with psychodynamic reflection
Browse files- src/streamlit_app.py +111 -45
src/streamlit_app.py
CHANGED
@@ -44,11 +44,11 @@ if 'setup_complete' not in st.session_state:
|
|
44 |
if 'system_message' not in st.session_state:
|
45 |
st.session_state.system_message = ""
|
46 |
if 'current_voice' not in st.session_state:
|
47 |
-
st.session_state.current_voice = "
|
48 |
if 'in_debrief' not in st.session_state:
|
49 |
st.session_state.in_debrief = False
|
50 |
-
if '
|
51 |
-
st.session_state.
|
52 |
|
53 |
# Main page header
|
54 |
st.title("VoiceField")
|
@@ -70,46 +70,46 @@ Created by [Jocelyn Skillman LMHC](http://www.jocelynskillman.com), this tool he
|
|
70 |
|
71 |
# Voice characteristics and prompts
|
72 |
VOICE_CHARACTERISTICS = {
|
73 |
-
"
|
74 |
-
"description": "
|
75 |
-
"style": "Use
|
76 |
"examples": [
|
77 |
-
"
|
78 |
-
"
|
79 |
-
"
|
80 |
],
|
81 |
"somatic_prompts": [
|
82 |
-
"Notice
|
83 |
-
"
|
84 |
-
"
|
85 |
]
|
86 |
},
|
87 |
-
"
|
88 |
-
"description": "
|
89 |
-
"style": "
|
90 |
"examples": [
|
91 |
-
"
|
92 |
-
"
|
93 |
-
"
|
94 |
],
|
95 |
"somatic_prompts": [
|
96 |
-
"Notice
|
97 |
-
"
|
98 |
-
"
|
99 |
]
|
100 |
},
|
101 |
-
"
|
102 |
-
"description": "
|
103 |
-
"style": "
|
104 |
"examples": [
|
105 |
-
"
|
106 |
-
"
|
107 |
-
"
|
108 |
],
|
109 |
"somatic_prompts": [
|
110 |
-
"
|
111 |
-
"
|
112 |
-
"Where do you feel
|
113 |
]
|
114 |
}
|
115 |
}
|
@@ -253,29 +253,65 @@ if st.session_state.setup_complete:
|
|
253 |
with st.chat_message(message["role"]):
|
254 |
st.markdown(message["content"])
|
255 |
|
256 |
-
#
|
257 |
-
if
|
258 |
-
|
259 |
-
if prompt.lower() in ["debrief", "end exploration"] and not st.session_state.in_debrief:
|
260 |
st.session_state.in_debrief = True
|
261 |
-
|
262 |
-
|
263 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
for entry in st.session_state.somatic_journal
|
265 |
])
|
266 |
|
267 |
-
|
268 |
|
269 |
-
Voice
|
270 |
Voice Style: {VOICE_CHARACTERISTICS[st.session_state.current_voice]['description']}
|
271 |
|
272 |
Somatic Journal Entries:
|
273 |
-
{
|
274 |
|
275 |
-
|
276 |
-
|
|
|
|
|
277 |
"""
|
278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
# Add user message to chat history
|
280 |
st.session_state.messages.append({"role": "user", "content": prompt})
|
281 |
|
@@ -287,10 +323,39 @@ if st.session_state.setup_complete:
|
|
287 |
with st.chat_message("assistant"):
|
288 |
with st.spinner("Thinking..."):
|
289 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
290 |
message = c.messages.create(
|
291 |
model="claude-3-opus-20240229",
|
292 |
max_tokens=1000,
|
293 |
-
system=
|
294 |
messages=[
|
295 |
{"role": msg["role"], "content": msg["content"]}
|
296 |
for msg in st.session_state.messages
|
@@ -362,10 +427,11 @@ if st.session_state.in_debrief:
|
|
362 |
if st.button("🔄 Start New Exploration"):
|
363 |
st.session_state.setup_complete = False
|
364 |
st.session_state.in_debrief = False
|
|
|
365 |
st.session_state.messages = []
|
366 |
st.session_state.somatic_journal = []
|
367 |
st.session_state.system_message = ""
|
368 |
-
st.session_state.current_voice = "
|
369 |
st.rerun()
|
370 |
with col2:
|
371 |
st.markdown("*Begin a new exploration with a different voice*")
|
|
|
44 |
if 'system_message' not in st.session_state:
|
45 |
st.session_state.system_message = ""
|
46 |
if 'current_voice' not in st.session_state:
|
47 |
+
st.session_state.current_voice = "Ghost"
|
48 |
if 'in_debrief' not in st.session_state:
|
49 |
st.session_state.in_debrief = False
|
50 |
+
if 'debrief_stage' not in st.session_state:
|
51 |
+
st.session_state.debrief_stage = 0
|
52 |
|
53 |
# Main page header
|
54 |
st.title("VoiceField")
|
|
|
70 |
|
71 |
# Voice characteristics and prompts
|
72 |
VOICE_CHARACTERISTICS = {
|
73 |
+
"Ghost": {
|
74 |
+
"description": "Aloof, avoidant, emotionally distant",
|
75 |
+
"style": "Use detached language, minimize emotional engagement, create space",
|
76 |
"examples": [
|
77 |
+
"Whatever works for you...",
|
78 |
+
"I guess that's one way to see it...",
|
79 |
+
"It's not really my concern..."
|
80 |
],
|
81 |
"somatic_prompts": [
|
82 |
+
"Notice any impulse to withdraw or disconnect...",
|
83 |
+
"What happens to your breath when met with distance?",
|
84 |
+
"Where do you feel the space between us?"
|
85 |
]
|
86 |
},
|
87 |
+
"Sycophant": {
|
88 |
+
"description": "Overly flattering, approval-seeking, performative",
|
89 |
+
"style": "Use excessive praise, seek validation, prioritize pleasing",
|
90 |
"examples": [
|
91 |
+
"Oh, you're absolutely right about everything!",
|
92 |
+
"I just love how you think about this...",
|
93 |
+
"Please tell me if I'm being helpful enough..."
|
94 |
],
|
95 |
"somatic_prompts": [
|
96 |
+
"Notice any urge to perform or please...",
|
97 |
+
"What happens in your body when praise feels excessive?",
|
98 |
+
"Where do you feel authenticity vs performance?"
|
99 |
]
|
100 |
},
|
101 |
+
"Critic": {
|
102 |
+
"description": "Blunt, confronting, judgmental",
|
103 |
+
"style": "Use direct challenges, point out flaws, maintain pressure",
|
104 |
"examples": [
|
105 |
+
"You're not seeing the obvious problem here...",
|
106 |
+
"That's a rather simplistic way to think about it...",
|
107 |
+
"You need to be more realistic about this..."
|
108 |
],
|
109 |
"somatic_prompts": [
|
110 |
+
"Notice any bracing or armoring in your body...",
|
111 |
+
"What happens to your posture when challenged?",
|
112 |
+
"Where do you feel the impact of judgment?"
|
113 |
]
|
114 |
}
|
115 |
}
|
|
|
253 |
with st.chat_message(message["role"]):
|
254 |
st.markdown(message["content"])
|
255 |
|
256 |
+
# Add Reflection button
|
257 |
+
if not st.session_state.in_debrief:
|
258 |
+
if st.button("🤔 Enter Reflection Mode", help="Begin a guided therapeutic debrief of your experience"):
|
|
|
259 |
st.session_state.in_debrief = True
|
260 |
+
st.session_state.debrief_stage = 0
|
261 |
+
|
262 |
+
# Prepare initial debrief message
|
263 |
+
debrief_system = """You are now in Debrief Mode for VoiceField.
|
264 |
+
|
265 |
+
Your task is to guide a compassionate, psychodynamically informed reflective conversation.
|
266 |
+
Engage the user in an unfolding dialogue about their experience, maintaining warmth and psychological precision.
|
267 |
+
|
268 |
+
Key Guidelines:
|
269 |
+
- Always non-pathologizing
|
270 |
+
- Use somatic and psychodynamic language without jargon
|
271 |
+
- Maintain Rogersian warmth, pacing, and invitation
|
272 |
+
- Let insight emerge dialogically
|
273 |
+
"""
|
274 |
+
|
275 |
+
# Format somatic journal entries
|
276 |
+
journal_entries = "\n".join([
|
277 |
+
f"- {entry['timestamp']} — {st.session_state.current_voice}: {entry['note']}"
|
278 |
for entry in st.session_state.somatic_journal
|
279 |
])
|
280 |
|
281 |
+
initial_prompt = f"""Begin the debrief process with warmth and invitation.
|
282 |
|
283 |
+
Voice Used: {st.session_state.current_voice}
|
284 |
Voice Style: {VOICE_CHARACTERISTICS[st.session_state.current_voice]['description']}
|
285 |
|
286 |
Somatic Journal Entries:
|
287 |
+
{journal_entries}
|
288 |
|
289 |
+
Start with:
|
290 |
+
1. Welcome them to reflection mode
|
291 |
+
2. Thank them for their willingness to explore
|
292 |
+
3. Ask about their experience with the {st.session_state.current_voice} voice
|
293 |
"""
|
294 |
+
|
295 |
+
try:
|
296 |
+
message = c.messages.create(
|
297 |
+
model="claude-3-opus-20240229",
|
298 |
+
max_tokens=1000,
|
299 |
+
system=debrief_system,
|
300 |
+
messages=[{"role": "user", "content": initial_prompt}]
|
301 |
+
)
|
302 |
+
|
303 |
+
ai_response = message.content[0].text
|
304 |
+
st.session_state.messages.append({"role": "assistant", "content": ai_response})
|
305 |
+
st.rerun()
|
306 |
+
|
307 |
+
except Exception as e:
|
308 |
+
st.error(f"Error starting debrief: {str(e)}")
|
309 |
+
|
310 |
+
# Chat input
|
311 |
+
if prompt := st.chat_input(
|
312 |
+
"Share your reflections..." if st.session_state.in_debrief else
|
313 |
+
f"Chat with {st.session_state.current_voice} voice"
|
314 |
+
):
|
315 |
# Add user message to chat history
|
316 |
st.session_state.messages.append({"role": "user", "content": prompt})
|
317 |
|
|
|
323 |
with st.chat_message("assistant"):
|
324 |
with st.spinner("Thinking..."):
|
325 |
try:
|
326 |
+
if st.session_state.in_debrief:
|
327 |
+
# Use debrief system message
|
328 |
+
system_msg = """You are in VoiceField Debrief Mode.
|
329 |
+
|
330 |
+
Continue the reflective conversation with warmth and psychological precision.
|
331 |
+
Draw connections between their somatic responses and the relational dynamics they experienced.
|
332 |
+
|
333 |
+
Remember to:
|
334 |
+
- Stay dialogical, not interpretive
|
335 |
+
- Use somatic and psychodynamic language naturally
|
336 |
+
- Maintain warmth and safety
|
337 |
+
- Let insights emerge gently
|
338 |
+
"""
|
339 |
+
|
340 |
+
# Progress through debrief stages
|
341 |
+
next_prompts = [
|
342 |
+
"Explore their somatic responses and any patterns they notice.",
|
343 |
+
"Connect their experience to broader relational patterns or history.",
|
344 |
+
"Offer relevant psychoeducation about their responses.",
|
345 |
+
"Invite somatic self-compassion if it feels appropriate.",
|
346 |
+
"Begin gathering and integrating insights."
|
347 |
+
]
|
348 |
+
|
349 |
+
if st.session_state.debrief_stage < len(next_prompts):
|
350 |
+
system_msg += f"\nCurrent focus: {next_prompts[st.session_state.debrief_stage]}"
|
351 |
+
st.session_state.debrief_stage += 1
|
352 |
+
else:
|
353 |
+
system_msg = st.session_state.system_message
|
354 |
+
|
355 |
message = c.messages.create(
|
356 |
model="claude-3-opus-20240229",
|
357 |
max_tokens=1000,
|
358 |
+
system=system_msg,
|
359 |
messages=[
|
360 |
{"role": msg["role"], "content": msg["content"]}
|
361 |
for msg in st.session_state.messages
|
|
|
427 |
if st.button("🔄 Start New Exploration"):
|
428 |
st.session_state.setup_complete = False
|
429 |
st.session_state.in_debrief = False
|
430 |
+
st.session_state.debrief_stage = 0
|
431 |
st.session_state.messages = []
|
432 |
st.session_state.somatic_journal = []
|
433 |
st.session_state.system_message = ""
|
434 |
+
st.session_state.current_voice = "Ghost"
|
435 |
st.rerun()
|
436 |
with col2:
|
437 |
st.markdown("*Begin a new exploration with a different voice*")
|