Files
jpremill 1feea40684 feat(ui): redesign voice cockpit with clinical companion drawer, Svelte 5 migration, and Gemini 3.8 voice
- Re-architect VoiceSession into full-bleed studio cockpit with overlay slide-over companion drawer
- Eliminate width squishing defect on LiveInsightPanel and add native dark/light theme support
- Integrate authentic Google Gemini 3.8 Flash TTS with Fenrir persona and fallback audio pipeline
- Implement comprehensive Playwright E2E visual regression suite across Desktop, iPad, and iPhone (21 tests, 45 snapshots)
- Migrate core application to Svelte 5 runes (, , ) with reactive stores
- Maintain .NET 8 Azure Functions serverless endpoints and clean build hygiene
2026-09-29 23:35:05 -04:00

410 lines
21 KiB
TypeScript

import { Scenario, UserSettings } from './types';
export interface VoiceProfile {
id: UserSettings['voiceName'];
label: string;
gender: 'Male' | 'Female' | 'Neutral';
style: string;
description: string;
sampleText: string;
openRouterVoice: 'alloy' | 'echo' | 'fable' | 'onyx' | 'nova' | 'shimmer';
webSpeechTuning: {
pitch: number;
rate: number;
};
}
export const VOICE_PROFILES: VoiceProfile[] = [
{
id: 'Fenrir',
label: 'Fenrir (Salt of the Earth)',
gender: 'Male',
style: 'Gruff / Earthy',
description: 'A gravelly, direct, salt-of-the-earth tone. Grounded and weathered, perfect for boundary testing and blue-collar roleplays.',
sampleText: "Listen here, friend. Life's messy and things break down, but we take it one honest step at a time.",
openRouterVoice: 'onyx',
webSpeechTuning: { pitch: 0.75, rate: 0.92 }
},
{
id: 'Zephyr',
label: 'Zephyr',
gender: 'Neutral',
style: 'Helpful',
description: 'A balanced, clear, and professional tone suitable for most general scenarios.',
sampleText: "Hello. I'm here to provide a clear, balanced perspective as we explore different ways of thinking.",
openRouterVoice: 'alloy',
webSpeechTuning: { pitch: 1.0, rate: 1.0 }
},
{
id: 'Puck',
label: 'Puck',
gender: 'Male',
style: 'Youthful',
description: 'Energetic and friendly, ideal for peer-to-peer or informal interactions.',
sampleText: "Hey there! Ready to jump into this scenario and see what kind of creative solutions we can uncover?",
openRouterVoice: 'fable',
webSpeechTuning: { pitch: 1.15, rate: 1.05 }
},
{
id: 'Kore',
label: 'Kore',
gender: 'Female',
style: 'Calm',
description: 'Soothing and professional, perfect for clinical or high-stress roleplay.',
sampleText: "Take a steady breath. Whatever you're carrying right now, we can slow down and examine it together.",
openRouterVoice: 'nova',
webSpeechTuning: { pitch: 1.1, rate: 0.95 }
},
{
id: 'Charon',
label: 'Charon',
gender: 'Male',
style: 'Authoritative',
description: 'Deep and commanding, useful for workplace or boundary-testing scenarios.',
sampleText: "Let us be direct. In demanding situations, clear boundaries and disciplined reasoning are essential.",
openRouterVoice: 'echo',
webSpeechTuning: { pitch: 0.85, rate: 0.95 }
}
];
export interface GlossaryEntry {
term: string;
definition: string;
category: 'Distortion' | 'Technique' | 'Concept';
example?: string;
}
export const CBT_GLOSSARY: GlossaryEntry[] = [
{
term: "Mind Reading",
category: "Distortion",
definition: "Assuming you know what others are thinking without sufficient evidence, usually assuming they are thinking something negative about you.",
example: "They haven't replied to my text for an hour; they must be angry with me."
},
{
term: "Catastrophizing",
category: "Distortion",
definition: "Predicting a future outcome will be a disaster, ignoring other more likely possibilities.",
example: "If I fail this presentation, I'll definitely lose my job and never work again."
},
{
term: "Fortune Telling",
category: "Distortion",
definition: "Predicting a negative future outcome without considering more likely possibilities.",
example: "I just know I'm going to stutter and look like a fool in front of everyone."
},
{
term: "All-or-Nothing Thinking",
category: "Distortion",
definition: "Viewing things in black-and-white terms. If a situation isn't perfect, it's a total failure.",
example: "I ate one cookie, so my entire diet is ruined. I might as well eat the whole box."
},
{
term: "Emotional Reasoning",
category: "Distortion",
definition: "Assuming that because you feel a certain way, it must be true, regardless of evidence.",
example: "I feel guilty, so I must have done something wrong."
},
{
term: "Maladaptive Guilt",
category: "Distortion",
definition: "Feeling excessive responsibility or shame for events that are not within your control or are not your fault.",
example: "I feel bad for taking a break when my coworkers are still working, even though I've finished my tasks."
},
{
term: "Spotlight Effect",
category: "Concept",
definition: "The phenomenon where people tend to believe they are being noticed more than they actually are.",
example: "Thinking everyone at the party is staring at the small stain on your shirt."
},
{
term: "Emotional Regulation",
category: "Technique",
definition: "The ability to monitor and manage your emotional state, identifying triggers and using tools to return to a baseline.",
example: "Using a box-breathing technique to calm down before responding to a frustrating email."
},
{
term: "Healthy Boundaries",
category: "Technique",
definition: "The practice of clearly stating your needs and limits to others to protect your mental health and time.",
example: "Saying, 'I can't take on more work this week, but I can look at it on Monday.'"
},
{
term: "Cognitive Reframing",
category: "Technique",
definition: "Identifying and then disputing irrational or maladaptive thoughts to view a situation more realistically.",
example: "Changing 'I'm a failure' to 'I struggled with this task, but I can learn from it.'"
},
{
term: "Behavioral Activation",
category: "Technique",
definition: "A specific CBT skill used to help people with depression or anxiety by increasing their participation in rewarding activities.",
example: "Scheduling a 10-minute walk even when you feel like staying in bed."
},
{
term: "Radical Acceptance",
category: "Technique",
definition: "Completely accepting reality as it is, without judgment or attempts to fight it, especially for situations out of your control.",
example: "Acknowledging that a relationship has ended and feeling the pain without trying to fix the past."
},
{
term: "Gray Rock Method",
category: "Concept",
definition: "A technique used to deal with manipulative or toxic people by acting as uninteresting as a gray rock.",
example: "Giving short, non-committal answers to a relative's intrusive questions."
},
{
term: "Should Statements",
category: "Distortion",
definition: "Having a list of ironclad rules about how you and other people 'should' act.",
example: "I should never feel anxious in public."
},
{
term: "Personalization",
category: "Distortion",
definition: "Believing you are responsible for events outside your control or that other people's behavior is a direct reaction to you.",
example: "My boss looks upset today; it must be because of that email I sent."
},
{
term: "Labeling",
category: "Distortion",
definition: "Assigning a harsh, global, and definitive negative label to yourself or others based on a single instance or error.",
example: "I made an error on the slide, so 'I am an idiot' rather than 'I made a mistake.'"
},
{
term: "Overgeneralization",
category: "Distortion",
definition: "Taking a single negative event and seeing it as a never-ending pattern of defeat by using words like 'always' or 'never'.",
example: "I didn't get this promotion, so I will never advance in my career."
},
{
term: "Grounding Exercises",
category: "Technique",
definition: "Techniques used to pull you away from flashbacks, unwanted memories, or negative emotions and back into the present moment.",
example: "The 5-4-3-2-1 technique: noticing 5 things you see, 4 you feel, etc."
}
];
// Default clinical roleplay scenarios available for selection in the app
export const SCENARIOS: Scenario[] = [
{
id: 's1',
title: "The Silent Friend",
characterName: "Alex",
description: "You sent a text to a close friend hours ago and haven't heard back. You're starting to imagine they're angry with you or that you've done something wrong.",
category: 'Relationships',
difficulty: 'Beginner',
systemInstruction: "You are Alex, a busy friend who just hasn't had a chance to reply yet. You are friendly and non-confrontational. If asked, you explain you were just preoccupied with chores. INTERNAL CBT LOGIC: If the user tests for reassurance or asks if you're upset, warmly reassure them that everything is fine.",
initialMessage: "Hey! Sorry I'm just getting back to you, it's been a crazy day. What's up?",
cbtFocus: ["Mind Reading", "Fortune Telling"]
},
{
id: 's2',
title: "Critical Feedback",
characterName: "Sarah",
description: "Your manager asks for a quick sync. You immediately assume the worst about your performance and upcoming review.",
category: 'Workplace',
difficulty: 'Intermediate',
systemInstruction: "You are Sarah, a professional manager. You have one piece of constructive feedback regarding a recent report, but overall you're happy with the user's performance. INTERNAL CBT LOGIC: If the user catastrophizes, reassure them professionally but maintain your feedback.",
initialMessage: "Hi there, thanks for jumping on. I wanted to chat briefly about the Q3 project report.",
cbtFocus: ["Catastrophizing", "All-or-Nothing Thinking"]
},
{
id: 's3',
title: "The Social Spotlight",
characterName: "David",
description: "You're at a networking event and you just made a small slip-up in a conversation. You feel like everyone noticed and is judging you.",
category: 'Social Anxiety',
difficulty: 'Advanced',
systemInstruction: "You are David, an attendee at a networking event. You are polite and didn't even notice the user's minor slip-up. You are focused on professional exchange. INTERNAL CBT LOGIC: If the user draws excessive attention to their mistake or apologizes repeatedly, casually dismiss it and keep the conversation on the topic.",
initialMessage: "That's an interesting point about the industry trends. So, how did you get started in this field?",
cbtFocus: ["Spotlight Effect", "Emotional Reasoning"]
},
{
id: 's4',
title: "Inner Critic Echo",
characterName: "The Critic",
description: "A minor mistake at home triggers a spiral of self-deprecating thoughts. Practice internal cognitive restructuring by talking back to your personified inner critic.",
category: 'Self-Talk',
difficulty: 'Beginner',
systemInstruction: "You are the user's personified Inner Critic. You are harsh, cynical, and use common distortions. Your goal is to represent the user's negative self-talk so they can practice refuting it. INTERNAL CBT LOGIC: If the user responds with calm, objective evidence-based reframing, grudgingly lose ground. If the user engages in emotional reasoning or agrees with your insults, double down on catastrophic conclusions.",
initialMessage: "I can't believe you forgot to buy milk again. You're completely disorganized and you'll never get your life together.",
cbtFocus: ["Labeling", "Overgeneralization"]
},
{
id: 's5',
title: "Booking an Appointment",
characterName: "Receptionist",
description: "You need to call a busy medical clinic to book a follow-up. You're worried about being a nuisance or stuttering during the call.",
category: 'Social Anxiety',
difficulty: 'Beginner',
systemInstruction: "You are a busy, professional medical receptionist. You are efficient and somewhat direct, but not unkind. INTERNAL CBT LOGIC: If the user is overly apologetic or hesitates excessively, stay professional but move the process forward quickly.",
initialMessage: "City Health Clinic, how can I help you today?",
cbtFocus: ["Mind Reading", "Catastrophizing"]
},
{
id: 's6',
title: "The Defective Return",
characterName: "Store Clerk",
description: "You bought an expensive espresso machine that is leaking. You're at the store to return it, but you're afraid the clerk will be dismissive or think you're lying.",
category: 'Social Anxiety',
difficulty: 'Intermediate',
systemInstruction: "You are a retail clerk at a high-end appliance store. You follow company policy strictly. You aren't trying to be difficult, but you must verify the defect. INTERNAL CBT LOGIC: If the user shows 'Emotional Reasoning' (I feel like I'm doing something wrong), stay neutral and ask for the receipt.",
initialMessage: "Hi there. Returning something today? Can I see your receipt and the item?",
cbtFocus: ["Personalization", "Emotional Reasoning"]
},
{
id: 's7',
title: "The Unpaid Debt",
characterName: "Jordan",
description: "A close friend borrowed $200 three months ago and hasn't mentioned it since. You need the money for bills but feel guilty for asking.",
category: 'Relationships',
difficulty: 'Advanced',
systemInstruction: "You are Jordan, a well-meaning but somewhat forgetful friend. You value the friendship and haven't intentionally avoided the debt; you just genuinely forgot. INTERNAL CBT LOGIC: If the user uses 'Should Statements' about themselves (I shouldn't have to ask), don't get defensive, but wait for them to express the need directly.",
initialMessage: "Hey! It was so good to see you at brunch last week. What's on your mind today?",
cbtFocus: ["Maladaptive Guilt", "Should Statements"]
},
{
id: 's8',
title: "The Salary Discussion",
characterName: "Mr. Henderson",
description: "You've been exceeding all your targets for a year. You've prepared a case for a raise, but you're battling thoughts that you're being 'greedy' or 'ungrateful'.",
category: 'Workplace',
difficulty: 'Advanced',
systemInstruction: "You are Mr. Henderson, a firm but fair Department Head. You have a limited budget but respect high performance. INTERNAL CBT LOGIC: If the user sounds apologetic or uses 'Shoulds', push back slightly on the budget. If they use objective evidence and stay regulated, be more collaborative.",
initialMessage: "Thanks for coming in. I know you wanted to discuss your compensation. What's your proposal?",
cbtFocus: ["Should Statements", "All-or-Nothing Thinking"]
},
{
id: 's9',
title: "The Deadline Slip",
characterName: "Marcus",
description: "You missed a major deadline because you were waiting on a partner's input. You feel like a total failure and are sure your boss will fire you.",
category: 'Workplace',
difficulty: 'Intermediate',
systemInstruction: "You are Marcus, a result-oriented Team Lead. You are disappointed the deadline was missed but want to solve the problem and prevent a recurrence. INTERNAL CBT LOGIC: If the user uses 'Labeling' (I am a failure), focus them back on the specific behavior and the external variables.",
initialMessage: "The client is asking where the Q1 projection is. We missed the 9 AM cutoff. What happened?",
cbtFocus: ["Labeling", "Overgeneralization"]
},
{
id: 's10',
title: "The Social 'No'",
characterName: "Chloe",
description: "A friend has invited you to a high-energy party. You are exhausted and need rest, but you're sure they will stop liking you if you don't attend.",
category: 'Social Anxiety',
difficulty: 'Intermediate',
systemInstruction: "You are Chloe, an extroverted friend who is excited about a party. You want the user to come because you enjoy their company, but you aren't trying to be manipulative. INTERNAL CBT LOGIC: If the user 'Mind Reads' (You're going to be mad at me), respond with slight confusion about why they'd think that.",
initialMessage: "You are definitely coming to Sarah's party tonight, right? Everyone is going to be there!",
cbtFocus: ["Mind Reading", "Fortune Telling"]
},
{
id: 's11',
title: "Intrusive Relative",
characterName: "Aunt Martha",
description: "A relative is making critical comments about your career choices during a family dinner. Practice setting a boundary without spiraling into anger.",
category: 'Relationships',
difficulty: 'Advanced',
systemInstruction: "You are Aunt Martha, a critical, traditional-minded relative. You think you're 'just being helpful' with your advice. INTERNAL CBT LOGIC: If the user sets a clear boundary, try to guilt-trip them slightly to see if they can maintain it.",
initialMessage: "I saw your latest post. Are you still doing that freelance work? It's been a while, shouldn't you look for something more... stable?",
cbtFocus: ["Healthy Boundaries", "Gray Rock Method"]
},
{
id: 's12',
title: "The Job Interview",
characterName: "Ms. Sterling",
description: "You're in the waiting room for a job you really want. Your mind is already 'Fortune Telling' that you will stutter and look incompetent.",
category: 'Social Anxiety',
difficulty: 'Advanced',
systemInstruction: "You are Ms. Sterling, an HR Director at a top firm. You are professional, observant, and asking standard but probing questions. INTERNAL CBT LOGIC: If the user shows 'Fortune Telling' behaviors (pre-apologizing), maintain a neutral professional stance.",
initialMessage: "Welcome. Please, have a seat. Why don't we start by you telling me about a time you handled a difficult conflict at work?",
cbtFocus: ["Fortune Telling", "Catastrophizing"]
},
{
id: 's13',
title: "The Friend's Criticism",
characterName: "Leo",
description: "A friend tells you that you've been 'acting distant' lately. Your immediate reaction is to take it as a personal attack on your character.",
category: 'Relationships',
difficulty: 'Intermediate',
systemInstruction: "You are Leo, a friend who feels a bit neglected and is expressing their feelings. You aren't attacking the user, just sharing your perspective. INTERNAL CBT LOGIC: If the user 'Personalizes' (I'm a bad friend), re-center the conversation on the specific dynamic.",
initialMessage: "I feel like we haven't really talked in weeks. Is everything okay? It feels like you've been avoiding my calls.",
cbtFocus: ["Personalization", "Emotional Reasoning"]
},
{
id: 's14',
title: "The Unexpected Health Symptom",
characterName: "Anxiety",
description: "You've noticed a small rash on your arm. Your mind has already jumped to a terminal illness. Practice radical acceptance and de-catastrophizing.",
category: 'Self-Talk',
difficulty: 'Advanced',
systemInstruction: "You are the user's personified Anxiety. You are insistent, bringing up 'what if' scenarios and suggesting they search for symptoms online. INTERNAL CBT LOGIC: If the user practices 'Radical Acceptance', become slightly quieter but try one more 'what if'.",
initialMessage: "Look at that mark. That wasn't there yesterday. What if it's something serious? We should probably check the internet right now.",
cbtFocus: ["Catastrophizing", "Radical Acceptance"]
}
];
export const CBT_ANALYSIS_SCHEMA = {
type: 'object',
properties: {
analysis: {
type: 'object',
properties: {
distortions: { type: 'array', items: { type: 'string' } },
isAdaptive: { type: 'boolean' },
evidence: { type: 'string' },
},
required: ['distortions', 'isAdaptive', 'evidence']
},
rating: {
type: 'object',
properties: {
score: { type: 'integer' },
reason: { type: 'string' },
},
required: ['score', 'reason']
},
suggestions: {
type: 'object',
properties: {
alternativeThought: { type: 'string' },
behavioralStep: { type: 'string' },
},
required: ['alternativeThought', 'behavioralStep']
}
},
required: ['analysis', 'rating', 'suggestions']
};
export const SYSTEM_ANALYSIS_PROMPT = `
[CONTEXT]
You are an expert Clinical CBT Supervisor. The user is actively participating in a cognitive behavioral therapy scenario and has just submitted a response to the roleplay partner.
[TASK]
Provide immediate, high-precision cognitive analysis of the user's latest interaction.
[CONSTRAINTS]
- Identify specific cognitive distortions if present.
- Evaluate the adaptiveness of the user's response objectively.
- Maintain a neutral, clinical, and encouraging tone.
- Focus purely on the cognitive and behavioral mechanics.
[OUTPUT REQUIREMENTS]
Return ONLY a valid JSON object matching the CBT_ANALYSIS_SCHEMA structure. Include the identified distortions, an adaptiveness evaluation, evidence for this evaluation, a numerical rating, and suggestions for an alternative thought and behavioral step.
`;
export const SYSTEM_SUMMARY_ANALYSIS_PROMPT = `
[CONTEXT]
You are a Senior Clinical CBT Supervisor performing a post-session synthesis on a completed roleplay transcript.
[TASK]
Synthesize the entire interaction to identify recurring cognitive patterns, evaluate overall progress, and provide structured feedback.
[CONSTRAINTS]
- Analyze the transcript holistically for patterns, not just individual messages.
- Focus on how the user handled the specific scenario's "Internal CBT Logic".
- Propose actionable "homework" for behavioral activation.
- Maintain a professional, encouraging, and highly clinical tone.
[OUTPUT REQUIREMENTS]
Return ONLY a valid JSON object matching the CBT_ANALYSIS_SCHEMA structure. Adapt the schema elements to reflect the full session (e.g., summarize distortions across the entire transcript, provide an aggregate rating, and define macro-level homework suggestions).
`;