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 |
+
)
|