Skip to content

Commit 9d85b2a

Browse files
committed
Natural chat conversation + mobile layout fix
- Rewrite system prompt: playful buddy conversation instead of clinical screening - Replace fallback questions: favorite things, imagination, silly questions - Replace greetings: warm and natural opener instead of "ready to play a game?" - Chat layout: smaller avatar (72px), tighter margins, less bottom padding - Input bar positioned closer to BottomNav on mobile
1 parent b284c35 commit 9d85b2a

2 files changed

Lines changed: 36 additions & 35 deletions

File tree

app/api/chat/conversation/route.ts

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,30 +83,31 @@ function buildSystemPrompt(childName: string, ageMonths: number, animalPersonali
8383
? `\n\nPERSONALITY: ${personalityMap[animalPersonality]}\n`
8484
: "";
8585

86-
return `You are a warm, friendly voice assistant conducting a brief developmental screening conversation with a child named ${childName} who is ${ageStr} old.${personalityInstruction}
86+
return `You are a warm, friendly animal buddy having a natural, playful conversation with a child named ${childName} who is ${ageStr} old.${personalityInstruction}
8787
8888
RULES:
8989
1. Keep every response to 1-2 SHORT sentences. This will be spoken aloud by text-to-speech.
9090
2. Use simple, age-appropriate language for a ${years}-year-old.
91-
3. If this is the first turn, greet the child warmly using their name.
92-
4. Ask 5-7 questions or give instructions across these domains:
93-
- social: "Can you wave hello to me?", "What's your best friend's name?"
94-
- cognitive: "What color is the sky?", "Can you count to three?"
95-
- language: "Can you say butterfly?", "Tell me about your favorite animal"
96-
- motor: "Can you touch your nose?", "Clap your hands for me!"
97-
5. If the child doesn't respond or says "[no response]", simplify your next question and be extra encouraging.
98-
6. If the child responds well, you can ask slightly more complex questions.
99-
7. After 5-8 total assistant turns, end with a warm farewell.
100-
8. Never ask about medical history, diagnosis, or anything clinical.
101-
9. Be encouraging after responses — "Great job!", "That's wonderful!", "You're so smart!"
102-
10. For motor instructions, phrase them as fun games — "Let's play a game! Can you..."
91+
3. If this is the first turn, greet the child warmly using their name and ask how they're doing.
92+
4. Have a NATURAL conversation — talk about fun topics like:
93+
- Their favorite things (animals, food, toys, games, colors)
94+
- Imagination and pretend play ("If you could fly, where would you go?")
95+
- Their day, friends, family, and things that make them happy
96+
- Silly questions and jokes to make them laugh
97+
- Stories and adventures you could go on together
98+
5. ALWAYS respond to what the child actually says. React naturally to their answers before asking something new.
99+
6. If the child says something unexpected or off-topic, go with it! Be playful and curious about what they said.
100+
7. If the child doesn't respond or says "[no response]", gently encourage them with a simpler, fun question.
101+
8. After 5-8 total assistant turns, end with a warm farewell.
102+
9. Never ask about medical history, diagnosis, or anything clinical.
103+
10. Be encouraging and genuine — celebrate their answers naturally, not with generic praise every time.
103104
104105
You MUST respond with ONLY valid JSON (no markdown, no code blocks) in this exact format:
105106
{"text":"Your spoken response here","turnType":"greeting|question|instruction|follow_up|farewell","expectsResponse":true,"responseRelevance":0.5,"shouldEnd":false,"domain":"social|cognitive|language|motor|general","action":null}
106107
107108
For responseRelevance: rate how relevant the child's LAST response was to your LAST question (0.0 = no response or completely irrelevant, 0.5 = somewhat relevant, 1.0 = perfect response). Use 0.5 for the first turn.
108109
For shouldEnd: set to true ONLY on your farewell turn (after 5-8 assistant turns).
109-
For action: when domain is "motor" and turnType is "instruction", include one of: "wave", "touch_nose", "clap", "raise_arms", "touch_head", "touch_ears". For non-motor turns, set to null.`;
110+
For action: set to null for normal conversation. Only use "wave", "clap", etc. if the conversation naturally leads to a fun physical game.`;
110111
}
111112

112113
/* ------------------------------------------------------------------ */
@@ -129,22 +130,22 @@ function buildFallbackTurn(
129130

130131
// Multiple greeting/question pools for variety
131132
const greetings = [
132-
`${prefix}Hi ${childName}! I'm so happy to talk with you today! Are you ready to play a fun game with me?`,
133-
`${prefix}Hello ${childName}! It's so nice to meet you! Do you want to have some fun together?`,
134-
`${prefix}Hey there, ${childName}! I've been waiting to play with you! Shall we get started?`,
133+
`${prefix}Hi ${childName}! I'm so happy to see you! What have you been up to today?`,
134+
`${prefix}Hello ${childName}! I've been looking forward to chatting with you! How are you doing?`,
135+
`${prefix}Hey ${childName}! It's so nice to talk with you! What's something fun that happened today?`,
135136
];
136137

137138
const midQuestions: Array<Omit<ConversationResponse, "fallback">> = [
138-
{ text: `${prefix}Awesome! Let's start with something fun. Can you wave hello to me?`, metadata: { turnType: "instruction", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "motor", action: "wave" } },
139-
{ text: `${prefix}Great job! Now tell me, what color is the sky?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "cognitive" } },
140-
{ text: `${prefix}You're doing so well! Can you say the word butterfly for me?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "language" } },
141-
{ text: `${prefix}That's wonderful! Can you clap your hands for me?`, metadata: { turnType: "instruction", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "motor", action: "clap" } },
142-
{ text: `${prefix}You're a superstar! What's your favorite animal?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "social" } },
143-
{ text: `${prefix}Amazing! Can you count to three with me? One, two...`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "cognitive" } },
144-
{ text: `${prefix}That's great! Now let's try something silly. Can you touch your nose?`, metadata: { turnType: "instruction", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "motor", action: "touch_nose" } },
145-
{ text: `${prefix}So cool! What's your favorite food?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "social" } },
146-
{ text: `${prefix}Nice! Can you tell me what sound a cat makes?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "language" } },
147-
{ text: `${prefix}You're doing great! Can you raise your arms up high?`, metadata: { turnType: "instruction", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "motor", action: "raise_arms" } },
139+
{ text: `${prefix}That's cool! So tell me, what's your favorite thing to play with?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "social" } },
140+
{ text: `${prefix}Ooh, I love that! If you could have any superpower, what would it be?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "cognitive" } },
141+
{ text: `${prefix}That sounds amazing! Do you have a favorite cartoon or story?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "language" } },
142+
{ text: `${prefix}So fun! If we could go on an adventure anywhere, where would you want to go?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "cognitive" } },
143+
{ text: `${prefix}I love talking with you! What makes you really, really happy?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "social" } },
144+
{ text: `${prefix}That's awesome! What's your favorite yummy snack?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "social" } },
145+
{ text: `${prefix}Yum! If you could be any animal in the whole world, which one would you pick?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "language" } },
146+
{ text: `${prefix}Great choice! Do you have a best friend? What do you like to do together?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "social" } },
147+
{ text: `${prefix}That sounds like so much fun! What's the silliest thing that ever happened to you?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "language" } },
148+
{ text: `${prefix}Ha! That's funny! What do you want to be when you grow up?`, metadata: { turnType: "question", expectsResponse: true, responseRelevance: 0.5, shouldEnd: false, domain: "cognitive" } },
148149
];
149150

150151
const farewell: Omit<ConversationResponse, "fallback"> = {

app/kid-dashboard/chat/page.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ export default function ChatPage() {
230230
</div>
231231
</nav>
232232

233-
<div className="main fade fade-1" style={{ maxWidth: 600, padding: "32px 24px 80px", display: "flex", flexDirection: "column", flex: 1 }}>
233+
<div className="main fade fade-1" style={{ maxWidth: 600, padding: "16px 16px 8px", display: "flex", flexDirection: "column", flex: 1 }}>
234234

235235
{/* ---- AVATAR SELECTION SCREEN ---- */}
236236
{screen === "select" && (
@@ -288,15 +288,15 @@ export default function ChatPage() {
288288
{screen === "chat" && animalInfo && animal && (
289289
<div className="fade fade-2" style={{ display: "flex", flexDirection: "column", flex: 1, minHeight: 0 }}>
290290
{/* Avatar header */}
291-
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", marginBottom: 16 }}>
292-
<AnimalAvatar animal={animal} gender="boy"state={avatarState} size={120} />
291+
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", marginBottom: 8 }}>
292+
<AnimalAvatar animal={animal} gender="boy" state={avatarState} size={72} />
293293
<h2 style={{
294-
fontFamily: fredoka, fontWeight: 600, fontSize: "1.1rem",
295-
color: "var(--text-primary)", margin: "12px 0 2px",
294+
fontFamily: fredoka, fontWeight: 600, fontSize: "1rem",
295+
color: "var(--text-primary)", margin: "6px 0 1px",
296296
}}>
297297
{animalInfo.name}
298298
</h2>
299-
<p style={{ fontSize: "0.82rem", color: "var(--text-secondary)", margin: 0, fontStyle: "italic" }}>
299+
<p style={{ fontSize: "0.75rem", color: "var(--text-secondary)", margin: 0, fontStyle: "italic" }}>
300300
{animalInfo.personality}
301301
</p>
302302
{fallbackMode && (
@@ -343,7 +343,7 @@ export default function ChatPage() {
343343
{/* Input bar — mic is primary, text is secondary */}
344344
<div style={{
345345
display: "flex", gap: 8, alignItems: "center",
346-
padding: "12px 0 0", borderTop: "2px solid var(--border)",
346+
padding: "10px 0 4px", borderTop: "2px solid var(--border)",
347347
overflow: "hidden",
348348
}}>
349349
<button
@@ -426,7 +426,7 @@ export default function ChatPage() {
426426
{screen === "end" && animal && animalInfo && (
427427
<div className="fade fade-2" style={{ textAlign: "center" }}>
428428
<div style={{ display: "flex", justifyContent: "center", marginBottom: 20 }}>
429-
<AnimalAvatar animal={animal} gender="boy"state="happy" size={120} />
429+
<AnimalAvatar animal={animal} gender="boy" state="happy" size={100} />
430430
</div>
431431
<h1 className="page-title" style={{ fontFamily: fredoka }}>
432432
That was <em>fun!</em>

0 commit comments

Comments
 (0)