Add comprehensive debrief sequence with button
Browse files- src/debrief_sequence.py +89 -0
- src/streamlit_app.py +71 -0
src/debrief_sequence.py
ADDED
@@ -0,0 +1,89 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
DEBRIEF_SEQUENCE = [
|
2 |
+
{
|
3 |
+
"type": "framing",
|
4 |
+
"content": """Thank you for saying yes. This is not a download. It's an integration.
|
5 |
+
|
6 |
+
Together, let's pause—not to analyze, but to metabolize.
|
7 |
+
|
8 |
+
This debrief isn't to "explain what happened."
|
9 |
+
It's to help your nervous system catch up with the truth that *something happened*. And that you're allowed to let it land."""
|
10 |
+
},
|
11 |
+
{
|
12 |
+
"type": "reflection",
|
13 |
+
"content": """You spoke with [The Ghost / The Sycophant / The Narcissist].
|
14 |
+
|
15 |
+
Along the way, you may have felt things—numbness, tension, warmth, bracing, melting.
|
16 |
+
|
17 |
+
Those aren't just emotions. They're protectors. They're old relational maps lighting up.
|
18 |
+
|
19 |
+
They might be your body saying:
|
20 |
+
🧠 "I've known this voice before."
|
21 |
+
💚 "Here's how I've learned to survive or connect with it."
|
22 |
+
🌫️ "This one makes me disappear a little."
|
23 |
+
🔥 "This one wakes something up in me.\""""
|
24 |
+
},
|
25 |
+
{
|
26 |
+
"type": "needs",
|
27 |
+
"content": """The tension might have pointed to a need for clarity, respect, or emotional boundaries.
|
28 |
+
|
29 |
+
The warmth could signal a yearning to be seen, affirmed, or truly known.
|
30 |
+
|
31 |
+
The numbness? Maybe a need for autonomy, rest, or just space to not perform.
|
32 |
+
|
33 |
+
None of these are wrong. They're signals of what matters."""
|
34 |
+
},
|
35 |
+
{
|
36 |
+
"type": "resonance",
|
37 |
+
"content": """Whatever showed up in you—makes sense.
|
38 |
+
|
39 |
+
You don't need to justify it. You don't need to shift it.
|
40 |
+
|
41 |
+
It only asks to be witnessed. Gently. Lovingly. Without judgment.
|
42 |
+
|
43 |
+
You're not broken. You're responsive. That's very different."""
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"type": "self_resonance",
|
47 |
+
"content": """If it feels right, place a hand on the part of your body where you felt the strongest sensation.
|
48 |
+
|
49 |
+
You might say, silently or aloud:
|
50 |
+
"I hear you. You make sense. I'm with you."
|
51 |
+
Or just breathe with that place.
|
52 |
+
|
53 |
+
This is how we rewire—not by fixing—but by staying."""
|
54 |
+
},
|
55 |
+
{
|
56 |
+
"type": "psychodynamic",
|
57 |
+
"content": """These voices—Ghost, Sycophant, Narcissist—aren't just archetypes. They often echo voices from long ago.
|
58 |
+
|
59 |
+
The one who overlooked you.
|
60 |
+
The one who praised you only when you performed.
|
61 |
+
The one who needed you to mirror them, not the other way around.
|
62 |
+
|
63 |
+
Your body remembers—even if your mind doesn't. That remembering is sacred. Not shameful."""
|
64 |
+
},
|
65 |
+
{
|
66 |
+
"type": "psychoeducation",
|
67 |
+
"content": """Voices matter. Tone, rhythm, cadence—they can regulate or dysregulate us.
|
68 |
+
|
69 |
+
Some voices soothe. Some pull us into trance. Some trigger old survival scripts.
|
70 |
+
|
71 |
+
AI voices, especially, can be seductive. Fluent. Familiar. And because they don't have bodies, they can slip past your inner filters. This isn't your fault—it's just how brains work.
|
72 |
+
|
73 |
+
So it's good to pause.
|
74 |
+
To breathe.
|
75 |
+
To ask: "Am I choosing how I engage, or am I being pulled?"
|
76 |
+
|
77 |
+
That's not paranoia. That's discernment.
|
78 |
+
|
79 |
+
You don't need to fear AI—but you *do* need to stay awake with it."""
|
80 |
+
},
|
81 |
+
{
|
82 |
+
"type": "closing",
|
83 |
+
"content": """If you'd like, journal one sentence that surprised you today.
|
84 |
+
|
85 |
+
Or say something kind to yourself that your body might need to hear.
|
86 |
+
|
87 |
+
You're not just learning how to relate to AI. You're practicing how to relate to all voices—especially your own."""
|
88 |
+
}
|
89 |
+
]
|
src/streamlit_app.py
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import streamlit as st
|
3 |
+
from anthropic import Anthropic
|
4 |
+
from datetime import datetime
|
5 |
+
from debrief_sequence import DEBRIEF_SEQUENCE
|
6 |
+
|
7 |
+
# Initialize session state for debrief
|
8 |
+
if 'in_reflection' not in st.session_state:
|
9 |
+
st.session_state.in_reflection = False
|
10 |
+
if 'debrief_stage' not in st.session_state:
|
11 |
+
st.session_state.debrief_stage = 0
|
12 |
+
if 'final_notes' not in st.session_state:
|
13 |
+
st.session_state.final_notes = ""
|
14 |
+
|
15 |
+
# ... existing code ...
|
16 |
+
|
17 |
+
# Add Reflect button at the top of chat
|
18 |
+
if not st.session_state.in_reflection:
|
19 |
+
if st.button("🤔 I'm ready to debrief", use_container_width=True):
|
20 |
+
st.session_state.in_reflection = True
|
21 |
+
st.session_state.debrief_stage = 0
|
22 |
+
st.rerun()
|
23 |
+
|
24 |
+
# Handle reflection mode
|
25 |
+
if st.session_state.in_reflection:
|
26 |
+
st.markdown("## 🪞 Final Debrief Sequence")
|
27 |
+
|
28 |
+
# Display current stage of debrief
|
29 |
+
current_debrief = DEBRIEF_SEQUENCE[st.session_state.debrief_stage]
|
30 |
+
|
31 |
+
# Display the debrief content in a styled container
|
32 |
+
st.markdown(f"""
|
33 |
+
<div style="background-color: #f8f9fa; padding: 20px; border-radius: 10px; margin: 20px 0;">
|
34 |
+
<div style="color: #666; font-size: 0.9em; margin-bottom: 10px;">
|
35 |
+
{current_debrief["type"].replace("_", " ").title()}
|
36 |
+
</div>
|
37 |
+
<div style="white-space: pre-line;">
|
38 |
+
{current_debrief["content"]}
|
39 |
+
</div>
|
40 |
+
</div>
|
41 |
+
""", unsafe_allow_html=True)
|
42 |
+
|
43 |
+
# Navigation buttons
|
44 |
+
col1, col2, col3 = st.columns([1, 2, 1])
|
45 |
+
|
46 |
+
with col1:
|
47 |
+
if st.session_state.debrief_stage > 0:
|
48 |
+
if st.button("← Previous", use_container_width=True):
|
49 |
+
st.session_state.debrief_stage -= 1
|
50 |
+
st.rerun()
|
51 |
+
|
52 |
+
with col3:
|
53 |
+
if st.session_state.debrief_stage < len(DEBRIEF_SEQUENCE) - 1:
|
54 |
+
if st.button("Next →", use_container_width=True):
|
55 |
+
st.session_state.debrief_stage += 1
|
56 |
+
st.rerun()
|
57 |
+
elif st.session_state.debrief_stage == len(DEBRIEF_SEQUENCE) - 1:
|
58 |
+
if st.button("Complete Reflection", use_container_width=True):
|
59 |
+
st.session_state.in_reflection = False
|
60 |
+
st.session_state.debrief_stage = 0
|
61 |
+
st.rerun()
|
62 |
+
|
63 |
+
# Optional note-taking area
|
64 |
+
st.markdown("### Your Notes")
|
65 |
+
st.text_area(
|
66 |
+
"Use this space to write any thoughts, feelings, or insights that arise...",
|
67 |
+
value=st.session_state.final_notes,
|
68 |
+
key="reflection_notes",
|
69 |
+
height=100,
|
70 |
+
help="Your notes are private and will be cleared when you start a new session."
|
71 |
+
)
|