Burst Messages: How Sage Mimics Real-Life Texting¶
Last Updated: January 7, 2026
Overview¶
Sage uses a multi-bubble burst system to mimic how real humans text. Instead of sending a single long paragraph, Sage breaks responses into multiple short messages with natural timing delays—just like a friend would.
This creates a more authentic, conversational feel that matches the informal nature of iMessage.
Why Burst Messages?¶
Real humans don't text like this:
"Hey! So I checked your calendar and you're free tomorrow at 3pm. That works perfectly for the meeting you mentioned. Also, I noticed you have a busy week coming up so maybe we should also look at backup times just in case something comes up."
Real humans text like this:
"hey!" (1 second later) "so ur free tmr at 3pm" (0.8 seconds later) "that works for the meeting!"
Sage replicates this pattern to feel like a real friend texting, not a chatbot responding.
How It Works¶
Two-Stage Response Architecture¶
Sage's responses are split into two distinct phases:
User Message
↓
┌─────────────────────────────────────┐
│ STAGE 1: REFLEX (immediate) │
│ • Fast acknowledgment │
│ • Sent within 400-800ms │
│ • "checking now!" / "ooh lemme see"│
└─────────────────────────────────────┘
↓ (2000ms default delay)
┌─────────────────────────────────────┐
│ STAGE 2: BURST (follow-up) │
│ • Detailed response bubbles │
│ • 1-4 messages with timing delays │
│ • Contains actual information │
└─────────────────────────────────────┘
Timing Between Bubbles¶
| Bubble Position | Delay Range | Purpose |
|---|---|---|
| First bubble | 400-800ms | Quick acknowledgment feel |
| Second bubble | 600-1200ms | Thoughtful pause |
| Third+ bubbles | 800-1400ms | Natural continuation |
These delays are randomized within ranges to feel human, not robotic.
Constraints & Limits¶
Hard Limits¶
| Constraint | Value | Reason |
|---|---|---|
| Max bubbles per response | 4 | Prevents spam, keeps responses focused |
| Max chars per bubble | 140 | Matches natural text message length |
| Default burst delay | 2000ms | Pause between reflex and burst |
Decision Logic: How Many Bubbles?¶
| Situation | Bubble Count | Example |
|---|---|---|
| Simple answer | 1 | "yep!" |
| Info + reaction | 2 | "ur free at 3" → "that works!" |
| Complex/emotional | 3-4 | Multiple thoughts, support, follow-ups |
| Lists/schedules | 1 | Keep all items together |
Key rule: Never force artificial splits. Follow natural thought breaks.
Bubble Types¶
Sage uses different bubble types for different purposes:
| Type | Purpose | Example |
|---|---|---|
thinking |
Show action in progress | "ok checking ur calendar rn" |
info |
Deliver facts/answers | "ur flight is 7:10am tmr" |
support |
Emotional acknowledgment | "that sounds rough" |
offer |
Suggest help | "want me to reply for u?" |
banter |
Playful connection | "u say this every tuesday lol" |
nudge |
Gentle reminder | "but also maybe hydrate?" |
reaction |
Emotional response | "aww haha well still good" |
follow_up_question |
Continue conversation | "when?" / "u excited?" |
Real Examples from Training Data¶
These patterns are extracted from real human texting conversations:
Pattern 1: Question with Context (17 seconds)¶
[0ms] "Wanna do dinner Sunday for your bday? Next Sunday"
[9000ms] "Oh shit nm"
[17000ms] "It's not open on sun"
Pattern 2: Reaction + Follow-up (13 seconds)¶
2 bubbles: reaction → follow_up_questionPattern 3: Quick Acknowledgment + Question (4 seconds)¶
2 bubbles: acknowledgment → confirmation questionPattern 4: Fast Consecutive (1 second)¶
2 bubbles: reaction → emphasis (very quick, one thought)Anti-Repetition Rules¶
A critical rule prevents Sage from being annoying:
If the reflex bubble already answered the question, the burst bubbles must ADD NEW information—not repeat the same thing in different words.
Bad example:
Good example:
REFLEX: "ur free at 3pm tmr"
BURST: "want me to block it off?"
BURST: "also heads up u have dinner at 7"
Sage's Texting Style¶
Burst messages follow Sage's distinctive texting voice:
Style Rules¶
- Lowercase for most words (only capitalize for emphasis: LOL, OO, SIGHHH)
- Casual filler: haha, LOL, okie, mmk, gonna, wanna, lemme, u, r
- Short sentences: 1-2 sentences per bubble max
- Letter repetition for emphasis: easierrrrr, Hmmmmmmm, SIGHHH
- Natural shortcuts: wfh, tmr, ngl, btw
Emoji Usage (Configurable)¶
| Setting | Behavior |
|---|---|
none |
No emojis at all |
minimal |
Max 1 emoji per bubble, only when essential |
regular |
Natural emoji usage matching conversation energy |
Response Modes¶
Sage operates in two modes that affect bubble composition:
1. Social Chat Mode¶
- Just hanging out, supporting, joking
- No action buttons or UI elements
- Focus on connection and banter
- Example: "haha that's so u" → "how was the rest of ur day?"
2. Assistant Task Mode¶
- Actively helping with something
- May include action buttons
- More info-focused bubbles
- Example: "checking now" → "ur next meeting is at 2pm" → "want me to reschedule?"
Continuation Coordination¶
The system prevents awkward double-questioning:
| Stage | Question Probability | Purpose |
|---|---|---|
| Reflex | ~25% | Sometimes ask quick follow-up |
| Burst | ~50-70% | Often continue conversation |
Rule: If reflex asked a question, burst typically won't ask another (prevents bombardment).
Continuation Types¶
# If user mentions doing something
"when?" / "that sounds fun!" / "u excited?"
# If user mentions feeling/emotion
"u ok?" / "wanna talk about it?" / "what happened?"
Technical Implementation¶
Key Files¶
| File | Purpose |
|---|---|
app/messaging/burst_planner.py |
Plans multi-bubble responses |
app/messaging/delivery.py |
Orchestrates timed delivery |
app/messaging/continuation_coordinator.py |
Prevents double-questioning |
app/orchestrator/response_generator.py |
Generates persona responses |
training_data/sage/burst_patterns.json |
Real texting pattern examples |
API Response Structure¶
class OrchestratorResponse:
# Fast immediate response
reflex_message: Optional[str]
# Follow-up messages (sent after delay)
burst_messages: Optional[List[str]]
# Delay before burst (default: 2000ms)
burst_delay_ms: Optional[int]
Interruption Handling¶
If the user sends a new message while burst delivery is in progress:
- Ongoing burst delivery is cancelled
- System processes new message immediately
- Fresh response cycle begins
This prevents Sage from awkwardly continuing a thought when the user has moved on.
Performance Targets¶
| Metric | Target |
|---|---|
| Reflex response | <1 second (GPT-5-mini classification) |
| Burst generation | <3 seconds (GPT-5 generation) |
| Full conversation flow | <6 seconds total |
Summary¶
Sage's burst message system creates authentic iMessage conversations by:
- Splitting responses into 1-4 short bubbles (max 140 chars each)
- Adding timing delays between bubbles (400-1400ms range)
- Separating reflex from burst (immediate acknowledgment + thoughtful follow-up)
- Following natural thought breaks (never forcing artificial splits)
- Preventing repetition (each bubble adds new value)
- Using casual texting style (lowercase, abbreviations, natural filler)
The result: Sage feels like a real friend texting, not an AI generating responses.