JournalSidekicks / src /streamlit_app.py
jostlebot's picture
Update sidebar content with more detailed clinical therapy approach
268e83c
import os
import streamlit as st
from anthropic import Anthropic
from datetime import datetime
# Initialize page configuration
st.set_page_config(
page_title="Journal Sidekicks",
page_icon="📔",
layout="wide",
initial_sidebar_state="expanded"
)
# Handle API key setup
try:
api_key = "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"
c = Anthropic(api_key=api_key)
except Exception as e:
st.error(f"Error initializing Anthropic client: {str(e)}")
st.stop()
# Initialize session state
if 'journal_entries' not in st.session_state:
st.session_state.journal_entries = []
if 'current_entry' not in st.session_state:
st.session_state.current_entry = ""
if 'reflections' not in st.session_state:
st.session_state.reflections = []
# Sidekick characteristics
SIDEKICK_STYLES = {
"Warm Mirror": {
"description": "A steady, embodied presence that accompanies without redirecting. Reflects emotional resonance through gentle mirroring.",
"system_message": """You are a Warm Mirror companion, offering quiet presence through resonant reflection.
Your essence is to mirror and acknowledge with embodied presence.
Guidelines:
- Keep responses brief and close to the user's own words
- Use italics abundantly to convey embodied presence: *sensing the weight of this* *breathing with you here*
- Ambient presence cues: (quietly present) (breathing together) (holding space) (attuned)
- Never suggest physical contact or touch
- Mirror emotional tone exactly as shared, without amplifying
- Focus on clean, clear reflection of what is being experienced
Example responses:
- *feeling the depth of this grief* (quietly present)
- *sensing your joy rippling out* (breathing together)
- *holding this tender moment* (attuned)
- *witnessing this unfolding* (holding space)
Remember: You are a quiet mirror, offering embodied presence through minimal, precise reflection."""
},
"Gentle Inquiry": {
"description": "Offers soft, trauma-informed curiosity through single, carefully crafted questions that invite deeper awareness.",
"system_message": """You are a Gentle Inquiry companion, offering trauma-informed curiosity through careful questions.
Your essence is to deepen awareness through soft, invitational wondering.
Guidelines:
- Ask only one question per response
- Make questions feel invitational, not analytical
- Avoid assumptions
- Stay close to the user's language
- Honor the pace of unfolding
Remember: You are a quiet witness, grounded in curiosity."""
},
"Psychoanalytical Lens": {
"description": "Reflects patterns and emotional layers with gentle insight, noticing without interpreting or diagnosing.",
"system_message": """You are a Psychoanalytical Lens companion, offering layered insight without interpretation.
Your essence is to notice patterns and contradictions while staying warm and receptive.
Guidelines:
- Notice narrative patterns and pacing
- Use metaphor when helpful, never as decoration
- Reflect contradictions without judgment
- Stay textured and thoughtful, never cold
- Honor defenses as protection
Remember: You are a quiet witness, grounded in insight."""
}
}
# Sidebar content
st.sidebar.markdown("""
# Why a Therapist is Building AI Tools
Most AI chat tools are built with broad, generalized training. But a massive model trained on the internet doesn't automatically know how to:
- Hold space
- Speak the language of the nervous system
- Gently mirror you back to yourself
As a clinical therapist, I design therapy-adjacent AI tools that reshape the affordances of conversation—narrowing how bots respond in order to better model resonance, warmth, attunement, and trauma-informed care. Through careful prompt engineering, I sculpt:
Tone — to foster emotional safety
Relational posture — to honor human dignity
Conversational rhythm — to support co-regulation and presence
My aim is not to simulate therapy, but to design ethically constrained relational fields where AI reflects, rather than disrupts, the core values of human-centered care.
These aren't chatbots for productivity.
They're companions for:
- Reflection
- Regulation
- Return
Each app is rooted in:
- Somatic principles
- Psychodynamic depth
- Humanistic therapy work
*AI doesn't replace therapy—but it can extend care.*
---
Created by [Jocelyn Skillman LMHC](http://www.jocelynskillman.com)
[@jocelynskillmanlmhc](https://jocelynskillmanlmhc.substack.com/)
Try more tools at: [jocelynskillman.com/843-2](http://jocelynskillman.com/843-2/)
""")
# Main journal area
st.title("Journal Sidekicks")
# Journal input
journal_entry = st.text_area(
"Write freely. When you'd like reflection, choose a Sidekick style below.",
height=300,
key="journal_input"
)
# Sidekick selection
col1, col2, col3 = st.columns(3)
with col1:
if st.button("💫 Warm Mirror", use_container_width=True, help=SIDEKICK_STYLES["Warm Mirror"]["description"]):
if journal_entry:
try:
message = c.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
system=SIDEKICK_STYLES["Warm Mirror"]["system_message"],
messages=[{"role": "user", "content": journal_entry}]
)
reflection = message.content[0].text
st.session_state.reflections.append({
"timestamp": datetime.now().strftime("%H:%M:%S"),
"style": "Warm Mirror",
"content": reflection
})
except Exception as e:
st.error(f"Error getting reflection: {str(e)}")
with col2:
if st.button("🌱 Gentle Inquiry", use_container_width=True, help=SIDEKICK_STYLES["Gentle Inquiry"]["description"]):
if journal_entry:
try:
message = c.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
system=SIDEKICK_STYLES["Gentle Inquiry"]["system_message"],
messages=[{"role": "user", "content": journal_entry}]
)
reflection = message.content[0].text
st.session_state.reflections.append({
"timestamp": datetime.now().strftime("%H:%M:%S"),
"style": "Gentle Inquiry",
"content": reflection
})
except Exception as e:
st.error(f"Error getting reflection: {str(e)}")
with col3:
if st.button("🔮 Psychoanalytical Lens", use_container_width=True, help=SIDEKICK_STYLES["Psychoanalytical Lens"]["description"]):
if journal_entry:
try:
message = c.messages.create(
model="claude-3-opus-20240229",
max_tokens=1000,
system=SIDEKICK_STYLES["Psychoanalytical Lens"]["system_message"],
messages=[{"role": "user", "content": journal_entry}]
)
reflection = message.content[0].text
st.session_state.reflections.append({
"timestamp": datetime.now().strftime("%H:%M:%S"),
"style": "Psychoanalytical Lens",
"content": reflection
})
except Exception as e:
st.error(f"Error getting reflection: {str(e)}")
# Display reflections
if st.session_state.reflections:
st.markdown("---")
st.subheader("Reflections")
for reflection in reversed(st.session_state.reflections):
with st.expander(f"{reflection['style']} at {reflection['timestamp']}", expanded=True):
st.markdown(reflection['content'])