File size: 8,152 Bytes
5f61ab7
 
 
896e97c
5f61ab7
08d36a2
5f61ab7
8fe0b1b
08d36a2
 
 
5f61ab7
 
896e97c
0a22466
0a70b04
0a22466
 
896e97c
0a22466
5f61ab7
896e97c
08d36a2
 
 
 
 
 
 
 
 
 
 
268e83c
 
08d36a2
 
268e83c
 
 
 
 
 
08d36a2
268e83c
 
 
 
 
 
 
d7abaca
08d36a2
 
 
 
 
 
 
 
 
 
 
 
 
d7abaca
08d36a2
 
 
 
 
 
 
 
 
 
 
 
 
d7abaca
 
 
08d36a2
 
 
0a70b04
08d36a2
 
 
 
0a70b04
268e83c
 
 
 
 
 
 
 
 
0a70b04
08d36a2
 
 
 
 
0a70b04
08d36a2
 
 
 
0a70b04
08d36a2
62f7a71
 
08d36a2
 
8fe0b1b
 
0a70b04
 
08d36a2
8fe0b1b
08d36a2
 
 
 
 
 
 
 
 
0a70b04
08d36a2
0a70b04
08d36a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a70b04
 
08d36a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
0a70b04
 
08d36a2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
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'])