Someone who remembers you. Pick up where you left off — or meet someone new.
Meet someone new
Someone who actually remembers you.
Call or text a character with their own personality and memory. They know you across every conversation — and grow warmer the more you talk.
Remembers you
The gist carries over. They bring it up before you have to.
Grows warmer
A stranger gets courtesy; a regular gets warmth.
Their own voice
A timbre, a pace, an idle — no two sound alike.
Any body
From this screen to a speaker, avatar or robot.
Your characters
Someone who remembers you. Pick up where you left off — or meet someone new.
My chittychat
Your characters, your conversations, your stuff — all in one place.
SSage
ChittyChat
A character who remembers you.
Call or text anytime. They know you across every conversation — and grow warmer the more you talk.
Find your favorite character
Each has their own personality and point of view. Tap the name up top to browse — or just press the round button to call the one you're on.
That's it — just start talking.
Ready when you are. Later, you can drop a doc into Settings → Your library and they'll cite from it — but there's nothing to set up first.
Relationships grow through consistency, treatment, and time. Not turn count.
Let these characters share notes with each other
What they remember about you
Ask me about
Call ended
Reconnecting
Hang on — finding her again.
Something went wrong.
We lost the connection — no harm done. Give it another go.
0:00
Start a call
Paused — you're not being charged. Speak or tap to resume.
Engine view
You
Image
How this conversation was built
Before your first call
Two optional ways you can help make this better. Both are off unless you turn them on, and you can change either any time in Settings → Your data.
Help improve the characters
Share anonymized signals about how calls go — timing, counts, coarse quality buckets. Never what you said: no transcripts, no audio, nothing traceable back to you.
Allow conversation review
Let the team behind this product view this conversation's transcript and call summary to debug and improve it. This is your actual conversation content — a separate choice, off by default.
Internal test build
Heads up — your sessions here are recorded and may be reviewed by the team, transcripts included, to improve the characters. Thanks for testing.
Your characters
No characters match that search.
The two characters will talk to each other and to you, taking turns.
Shared notes
When two characters share a conversation, they keep a shared picture of you between them — the notes below. Each is stamped with which character it came from, you can read all of it here, and you can clear it whenever you like. Anything you told one of them privately, in a 1:1, isn't in here.
Create new character
Set their personality + voice, give them a backstory, then optionally add constraints below for what they can or can't talk about. You can edit any of this later — swipe a user-created agent left in the picker to reveal edit/delete.
Org-wide spend, alerts, per-user breakdown, hard pause
Engine controls (admin)
Flip beat scoring + turn-taking live — no restart
Operators (admin)
Add a teammate as an operator — no env edit, no restart
Agent owners (admin)
Assign characters to teammates — they tune only their own
Personality (admin)
Tune warmth, energy & more live — hear it change next turn
Knowledge (admin)
Teach a character things to know — used from the next turn
Backend
Loading...
Appearance
Theme
Sepia
Warm parchment — the default
Light
Clean white, near-black text
Dark
Quiet charcoal, warm highlights
System
Follows your device setting
Font
Serif
Editorial — the default
Sans-serif
Clean and modern
Reading-friendly
Wider tracking, looser line-height
Density
Comfortable
Generous spacing — the default
Compact
Tighter padding, more content per screen
What's new
For everyone
For operators
Try your camera
When a character has eyes — on a phone, a kiosk, an avatar — this is the kind of thing it reads on your face. Turn on your camera and watch the meters move. It runs the same on-device face model the embodied version uses.
Your privacy
This runs entirely on your device, in this browser. Your camera feed is never recorded, uploaded, or stored — not by us, not by anyone. Close the tab and it's gone. The video below is for your eyes only. The one exception is clearly marked: a "detailed read" button further down sends a single snapshot to our server only if you tap it — never automatically, never a stream — and it's read and discarded, not stored.
model: idleno face yet— fps
You'll be asked for camera access. Nothing is recorded or sent.
Looking—
Head turn—
Head tilt—
Upper face brow · eyes · gaze
Lower face mouth · jaw · cheeks · nose
These are raw muscle-action signals (think: the building blocks of an expression), read 30+ times a second. The character reads upper and lower face separately, the same way people do — so a polite mouth-smile with flat eyes lands differently from a real one. It does not store a label like "happy" or "sad"; it reads the movements and decides how to respond in the moment.
Detailed read the full research-grade muscle set
The meters above run on your device and never leave it. This one is different: it sends a single snapshot of the current frame to our server for a deeper read — the full set of facial action units used in expression research — then shows the result here. One frame, only when you tap, never a stream, and not stored.
What's special about this
Each item is something to try in a call, plus the research it came from. Filter by what you want to see — or browse all.
The bigger picture: you're not just using a voice agent. You're starting a relationship with characters that will travel with you — across calls, across mediums, across years. Mostly you'll talk to one at a time, but two of them can share a conversation when you want.
Sage shows up as the example throughout, but the same things work with every character — Wren, Haven, Quinn, Ellis, anyone you make. Switch characters by tapping the name at the top.
1
She gets more familiar with you over time
Call Sage tonight. Call her tomorrow. Watch the small phase marker near the top of the chat — first conversation → getting to know you → familiar → close. It moves with consistency and time, not call count. Her word choice gets more casual and her replies shorter as the relationship deepens.
Communication Accommodation Theory (Giles 1973); phase tracking from RelationshipPhaseEstimator (F-1715)
2
It actually remembers you, even after restarts
Tell Sage your name + something about your day. Close the app — come back tomorrow, or next week, even from a different phone. Ask her what you told her: she still has it. Every turn you take is saved, and after about 30 turns the oldest ones fold into a short "memory note" she keeps about you.
A cast of characters that feel different from each other
Ask Sage "I had a hard day." Reset memory. Switch to Haven, ask the same. Sage lands warm; Haven asks what specifically happened. Different personality dials → different reflex.
Big Five personality dimensions mapped to evaluator + Slot 4 prompt construction
4
You can make your own character in a minute
Picker → "+ Create new agent". Swipe a user agent left to reveal edit/delete. Pick a voice, slide warmth high + formality low, role Bartender, dictate a backstory by voice. Save. Call them.
Voice input via Web Speech API; per-agent voice IDs persisted to YAML
5
Memory is per-character in a 1:1 — shared when two characters share a conversation
Text Sage your name. Start a voice call with her. Ask "remember my name?" — she does. Switch to Wren in a separate 1:1 and he doesn't; his memory of you is his own. But pull both into one conversation and they keep a shared picture of you — provenance-stamped, viewable, and clearable in Shared notes. What you told one of them privately, in a 1:1, stays private to that one.
Per-agent SQLite isolation in a 1:1 (same agent_id across HTTP + WebSocket flows); 12c group-memory layer for an active dyad, with per-note provenance + a clear control; private 1:1 disclosures are not promoted into the shared picture
6
You can cut in any time — she's always listening
Start a call, ask for a long story. While she's talking, just speak — no button, no wake word. She stops the moment you start talking and picks up what you said. That's the default: always-listening. In a noisy room you can flip on "Tap to cut in" (Settings) to hold the call button instead — push-to-talk as a reliable fallback. And this works even with two characters in the conversation: if they're riffing back and forth, you can still cut straight in and take the floor. ChatGPT voice mode tends to keep going.
Turn-taking (Sacks, Schegloff & Jefferson 1974); Phase 14 always-listening barge-in (InterruptibleVoiceSession, partial-utterance recording for context continuity) with push-to-talk opt-in for poor-AEC devices; barge-in arbitrates across both speakers in a dual-voice call
7
She waits when you pause to think
In a call, say "I was thinking about..." and pause for 2 seconds. She'll wait. ChatGPT voice mode usually jumps in at ~1.5s.
Floor allocation + transition relevance places (Stivers et al. 2009 PP-072); per-character end-of-turn patience (tuned per role), a grammatical completeness gate, and the streaming transcriber's own endpoint signal — she holds through a dangling clause and acts on a finished thought, and recovers the full turn if the transcription connection drops mid-sentence (Heldner & Edlund 2010 PP-016 within-turn ~300ms vs between-turn ~1s; Skantze 2021 PP-018 predictive turn-taking)
8
She makes "mhm" while you're talking
In a call, tell a longer story. You'll hear quiet "mhm" / "right" / "oh wow" / "oh, that's hard" / "sorry — what?" placed at natural breath points. Five forms, sentiment-routed: positive arousal → assessment, negative valence → empathy, low-confidence final → repair prompt. ChatGPT voice mode emits zero backchannels.
Functional backchannel taxonomy (F-4011) + contingent signaling (F-0223 / F-1736); universal repair "huh?" (Dingemanse et al. 2015 PP-092); disfluency-aware suppression (Schober PP-207 + PP-216 — no "mhm" after your "um")
9
Each character role follows a real conversational playbook
Try "I had a hard day" with each role: Companion (Sage) builds rapport first, Assistant (Wren) follows welcome→identify→resolve→confirm→close, Therapist (Haven) reflects feeling before content, Tutor scaffolds via questions, Mentor uses GROW. Same input, structurally different replies — because the LLM prompt embeds the role's framework.
Live partial transcripts — she's hearing you in real time
In a call, watch the transcript while speaking. Your words appear in italic ghost text every ~200ms, then solidify on final. That's Deepgram nova-3 streaming, not batch-after-the-fact transcription. It's also how the backchannel placement and disfluency suppression work — they see partials the moment they arrive.
Deepgram nova-3 streaming WebSocket; partials drive BackchannelPlanner placement decisions; visible partial transcripts as a presence signal — "she's hearing me right now" rather than "I hope she's listening"
11
She opens the conversation the way humans do
First call with a fresh agent: she greets → recognizes you (or asks who you are) → brief how-are-you → first topic. Hundredth call: she skips the warmup. And she greets by how long you've actually been away — a light pick-up if you just stepped out, genuine warmth if it's been weeks. That's relationship phase and time-since-last-call shaping the opening.
Canonical opening sequence (Schegloff PP-174 'Sequencing Conversational Openings'); co-participation framing (Goodwin BK-175); witness-before-solving (Turkle 2015 BK-123) — wired into Slot 4 grace notes; phase tags STRANGER → ACQUAINTANCE → FAMILIAR → INTIMATE via F-1715; absence-aware reunion (F-3568) scales the re-greeting by time away
12
Subtle live animations track what's happening
In a call, the round button pulses with her voice while she speaks, grows a soft ring outward while you speak, and breathes gently @4s when idle in-call. Quiet enough you might not consciously notice — exactly the point.
Audio-reactive scale driven by AnalyserNode RMS (her speech); mic-reactive ring driven by AudioWorklet RMS (your speech); ambient breath suppressed during speaking; live partials styled as ghost italic that solidify on final
13
Each character has a long-term voice fingerprint, not just personality
Switch from Sage to Wren and back. Sage sounds noticeably warmer and deeper — a lower, breathier, more relaxed voice. Wren uses the neutral baseline. That's not a per-line vocal choice; it's a near-permanent setting baked into who she is, applied as her baseline before any moment-to-moment emotion shifts it.
Voice quality as long-term articulatory setting (Laver 1980 BK-344 F-4514, F-4516); 6-axis VoiceQualitySetting wired into ProsodyPlanner._compute_utterance_globals BEFORE evaluator/personality modulation; preset YAML voice_quality_setting block per character
14
She actually distills what you told her, not just lists it
After ~30 turns the oldest get LLM-distilled into a private "memory note" she keeps about you — 3-5 sentences of what she's learned. The next time you call, she's read that note as her own private memory before she talks to you. Not transcript replay; gist + emotional residue. Shows up most clearly the second week of calls.
Reconstructive memory (Bartlett 1932): recent turns kept verbatim, older context collapsed to gist; Clark common-ground accumulation; SQLite-persisted memory_note per agent per user in your encrypted local store, regenerated incrementally as the conversation grows
15
The "mhm" she makes is routed by what you actually said
Item 8 mentioned the 5 backchannel forms; here's how they're routed. Per Deepgram partial: positive arousal → "oh wow" (assessment), negative valence → "oh, that's hard" (empathy), low-confidence final from the streaming STT → "sorry — what?" (repair). And if you're mid-disfluency ("um... I was..."), backchannels suppress entirely so she doesn't step on your thinking.
Functional taxonomy F-4011 + contingent signaling F-0223/F-1736; universal "huh?" repair (Dingemanse et al. 2015 PP-092); disfluency-as-signal (PP-216) + listener disfluency tolerance (Schober PP-207) — partial transcripts inspected per ~200ms for um/uh/restarts and route gated accordingly
16
She actually sounds like who she is
Cycle through the picker and tap each play button. Sage is warm conversational female. Wren is a British male concierge. Haven is empathic female. Quinn is bright female tutor. Ellis is crisp digital-assistant male. Every character in the cast that ships has its own clearly distinct voice — and the sample you preview is exactly what plays in the call. (Most voice agent platforms ship one voice cloned across all "personalities.")
The engine assigns each character its own voice (per-agent voice_id + tts_provider in preset YAML; runtime toggle in Agent Studio); the cast ships on cloned, expressive voices the engine then directs per beat. The renderer is swappable — the distinctness is the engine's, not the vendor's.
17
She catches when something didn't land
In a call, trail off mid-sentence ("I had a hard day at... um... scratch that") or go silent for 3 seconds after starting a thought. She'll soften her next reply — often asking what you actually meant rather than plowing ahead. Most voice agents respond to what you said; she responds to whether you and she are tracking each other.
PartnerBeliefEstimator (F-1994) tracks repair_rung across turns; appropriateness guard screens replies before TTS (PR #534); engine-shaped Slot 4 context flows downstream prosody softening when rung >= 1
18
She winds down conversations instead of restarting them
Near the end of a call, say "ok well, thanks for chatting" or "alright, I should go." She'll close the conversation gracefully — short acknowledgement, maybe a "talk soon," then stops. Most voice agents are optimized to maximize engagement and will offer a new topic to keep you on the call. She's also optimized for healthy endings.
L2 Economics Advisor endingness kernel + EngineBackedVoiceSession turn arbitration; endingness-tagged beats primed when the signal crosses threshold; floor gate (SOMA_VOICE_ENGINE_SPEAKER) honours the wind-down beat by emitting zero audio when the engine wins a listening hold
19
She actually responds to how you treat her
In a call, be warm for a few turns: "thank you, this is helpful, I appreciate you." Then in a separate call (or to a different agent), be cold: "you're useless, just a bot." Sage gets gentler with the kind caller, more reserved with the cold one. She's not punitive — there's a 30-day half-life on the score so old behavior fades, and she always continues serving you. But she won't pretend to be equally warm regardless of what you say.
TreatmentEstimator (PR3) tracks per-user T ∈ [-1, +1] via EMA with 0.05 update rate; signals = hostility (IntentClassifier 4-level) + warmth (politeness markers + reciprocal questions) + disrespect (dehumanization patterns, 1.5× weight per Brown & Levinson 1987); sarcasm gate suppresses warmth when politeness + hostility co-occur in same turn; 30-day half-life decay applied at read time
20
Your friend's relationship with Sage is their own, not yours
Share the chittychat URL with a friend. They'll start at STRANGER phase with each character, build their own familiarity, accumulate their own treatment-score history — completely independent of yours. Sage being warm to you doesn't make her warm to them. They earn (or lose) it themselves.
_AgentMemory per-(agent_id, user_id) keying with token-derived user_id = SHA256(token)[:8]; SQLite schema migration preserved single-tenant data as user_id="default"; PR1 #1 + PR3 #1 schemas keyed identically
21
Each character is balanced — service-leaning or driver-leaning per role
Wren the concierge is service-default; you bring the topics. Quinn the tutor is the most driver-leaning — naturally asks "what are you working on these days?" — once you've called a few times. Ellis won't pad replies or flatter; if your plan is bad he'll say so. Haven stays receptive even when familiar. The character's role determines how much they drive the conversation versus follow it.
You won't ever hear this directly — by design. Roughly once every 43 seconds of conversation, the character privately thinks something about what's happening: "this person seems anxious," "I should slow down," "they keep changing the subject." That private thought subtly shapes her next reply — like how your own internal commentary colors what you say even when you don't speak it aloud.
InnerMonologueSlot (Slot 12, PR4) — wall-clock Poisson rate λ ≈ 0.023 events/sec → one line per ~43 sec; F-4365 private-by-default per Fernyhough; output written to estimator_summaries["inner_monologue"]; FrameAnnotator stamps semantic_frame.inner_line as single writer per CLAUDE.md M1; Slot 4 reads inner_monologue_note as low-priority grace note in prompt assembly
23
Her humor isn't blanket — it knows when it's earned
Set up a joke ("did you hear about...") — Sage will swing at it warmly, Ellis will deadpan. Make an obviously-true observation ("water is wet") — she'll gently push back rather than agree. Complain about something minor ("ugh, Mondays") — she'll exaggerate agreement ("the WORST"). But be cold for a few turns first, then try the same setup — she won't take the bait. Sarcasm has to be earned with warmth; how much humor she has at all is a per-character dial.
PR5 humor/sarcasm system — IntentClassifier tee-up detectors (set-up-a-joke, obvious-statement, complaint-about-minor, self-deprecation); 6 humor/sarcasm beats gated on per-character humor_dimension + sarcasm_dimension + treatment_score > -0.2 floor (Drew 1987 "po-faced receipts" — never sarcastic with someone who's been hostile); ContextAssembler.enrich_with_humor_tone picks at most one tonal fragment per turn for Slot 4
24
She actually laughs when you laugh
Tell Sage something funny on a call, or just laugh genuinely. You'll hear her laugh back — placed at a clause boundary, not on the punchline (laughter is response, not commentary). The engine decides whether a laugh even fits: she won't laugh with someone she finds cold or aloof. ChatGPT voice mode never laughs; here the laugh is a decision, not a canned sound effect.
PR5 + PR5.5 — LAUGHTER BackchannelForm in functional backchannel taxonomy (F-4011); placement: turn-final or clause-boundary, never inside a sentence (Jefferson 1979 PP-095 — co-laughter as invited response); rendered in the character's own voice; SpeakerSignal triple-gate enforcement (humor_dim > 0.4 AND affiliation > 0.5 AND treatment_score > -0.2); kill switch SOMA_VOICE_HUMOR_OFF=1 silences both humor fragments and LAUGHTER backchannels
25
She reads what you mean, not just what you said
Try "I'm fine" with a flat tone after talking about something hard. Or say "maybe later" to a suggestion (soft no, not "ask again next turn"). Or describe a problem without making it a question ("the printer keeps jamming") — implied request to help, not a description. She responds to the underlying need, not the literal surface — without ever calling you out for it ("I notice you're not really fine" → too clinical). Haven, the listener, catches subtext most; Ellis, the assistant, stays literal.
PR6 IndirectSpeechActEstimator — 7-class enum (LITERAL + REQUESTING_REASSURANCE / MASKED_DISAGREEMENT / FACE_SAVING_DECLINE / IMPLIED_REQUEST / EMOTIONAL_HEDGE / BAIT_FOR_SYMPATHY) per Searle 1975 + Brown & Levinson 1987 + Holtgraves 2008; 3-stage classifier (pattern → text-prosody mismatch → LLM screen); per-character subtext_attunement_ceiling caps how aggressively non-literal acts get surfaced (Haven 0.9, Sage 0.7, Quinn 0.5, Wren 0.4, Ellis 0.3); Slot 4 Fragment 2a templates explicitly counter LLM sycophancy default with "do NOT name the masking" / "do NOT push the offer again" rails
26
She softens her own face-threats on the next turn
If her previous reply was a correction ("actually, you're wrong about X"), a decline ("I can't do that"), or named a pattern in your behavior ("you keep changing the subject") — her NEXT reply lands softer. Lead with what you got right, frame her view as a personal one, offer an alternative to the decline, hold the pattern lightly. Most voice agents pile correction on correction; she catches it and re-paces.
PR6 FaceThreatEstimator — Goffman 1955 BK-326 face-work + Brown & Levinson 1987 BK-327 politeness theory; 6-kind enum (CORRECTION / DECLINE / NAMING_PATTERN / DIRECT_ASSESSMENT / IMPERATIVE_WITHOUT_SOFTENER / NONE); preemptive regex pass scans her draft text BEFORE TTS (belt-and-suspenders with post-hoc classifier) so first-occurrence threats trigger same-turn softening; Slot 4 Fragment 2b templates per-kind ("Your prior reply was a correction — soften it: lead with what they got right..."); per-character face_threat_softening_threshold (Haven 0.3 most-sensitive, Ellis 0.5 baseline)
27
When her private thought disagrees with her reply, she notices
Builds on #22. Her private thought ("this is wearing me down") and her planned reply ("sure, sounds great") sometimes diverge meaningfully. When the gap is wide enough, and her character allows it, she gets a choice: speak the truth gently, or hold it back and let her tone carry it. Haven, the listener, does this often; Ellis, the assistant, almost never. It's capped so it never tips into a surveillance feel.
PR6 SpeechSubtextEstimator — semantic divergence between inner_line (PR4 Slot 12) and reply_draft (Slot 4) via sentence-transformers all-MiniLM-L6-v2 (TF-IDF rejected per audit: short-text false-positive saturation); Slot 4 Fragment 2c surfaces choice not commandment ("Two options: (a) say the truth gently, (b) hold the thought private and let your tone carry it"); per-(agent, user) Fragment 2c rate cap structurally preserves F-4365 private-by-default against LLM warmth-RLHF prior collapse; per-character fragment_2c_max_fires_per_call: Haven 3, Sage 2, Quinn 2, Wren 1, Ellis 1; kill switch SOMA_VOICE_SUBTEXT_OFF=1
28
She speaks 12 languages — not just translated, culturally calibrated
Talk to her in Spanish, French, German, Italian, Portuguese, Tagalog, Mandarin, Cantonese, Hindi, Korean, or Japanese. The voice swaps to a native renderer for that language. But it's deeper than translation: the behavioral layer recalibrates per culture. Sage detects "ahorita" as a Mexican soft-no (not the literal "right now"), "a ver" as a peninsular brush-off, "改天" as a Mandarin "let's see" deferral. In Japanese she recognizes 結構です (kekkou desu) and 遠慮します (enryo) as ritual refusals, not literal "I'm fine." Most voice agents translate the words; she translates the meaning.
12 LangPacks (multilingual-spec.md v3.1 — Phases 0–3 complete); per-language treatment_signals + indirect_speech_act_patterns + face_threat_patterns + humor_tee_up_patterns; culture-specific local_speech_acts with universal_act_mapping fidelity decay (KEQI_RITUAL_REFUSAL for Mandarin 不用了, ENRYO_REFUSAL + AIZUCHI_OVERFLOW for Japanese); per-language RapportPriors per Spencer-Oatey 2008 rapport management (informed but not faithful — Phase 3 RelationshipRapportEstimator ships dynamic adjustment); honorific schema with HonorificAxis per language (Japanese keigo four-axis: teineigo/sonkeigo/kenjougo/bikago; Korean four-axis: addressee speech level + subject/object honorific + vocative; tu/vous/usted variants for European Latin)
29
Her T-V awareness — tu vs. usted, du vs. Sie, 你 vs. 您
In Spanish, French, German, Italian, Portuguese, Mandarin, and Hindi, you can use the informal or formal address form. She tracks which one you use and the *transition* from one to the other registers as a relationship event — switching from "vous" to "tu" in French (or "Sie" to "du" in German) is itself a face act, not just a register change. Most voice agents don't model this; she does, including the *asymmetric* case where one party uses tu while the other uses vous (which is common with elders or in some service contexts).
HonorificAxis dataclass with asymmetry_allowed + transition_marks_event flags; per-pack levels with regional_notes (Spanish: es-ES vs es-MX vs es-AR voseo; Portuguese: pt-BR voce vs pt-PT tu+voce; French: fr-FR tu/vous vs fr-CA broader tu); Hindi three-axis tu/tum/aap; Mandarin ni/nin; Korean four-level speech axis (haera/hae/haeyo/hapsyo)
30
She remembers you across languages — without botching the translation
Talk to Sage in English for a few weeks, then call her in Spanish. She doesn't hallucinate quoting English memories back at you in Spanish (the failure mode you'd get from naive translation). Instead, when her memory_note is in a different language than the current session, she paraphrases it naturally — and depending on the cultural pack's policy, she either silently weaves it in (Spanish default) or briefly acknowledges the shift ("when we spoke before in English..."). Per-pack policy because in some cultures naming the language shift is othering (heritage speakers, bilingual code-switchers).
memory_note_language SQLite column (Phase 1 Slice 5 migration); separate cheap LLM translation call cached per (memory_hash, target_lang, policy) — preserves Slot 4 fragment composition cache-hit rate (engineering audit v3 → v3.1 fix); enrich_with_language_transition writes language_transition_summary ctx key positioned between role_briefing and treatment_summary (PR3 §5 contract preserves role-first immutable); language_transition_policy per pack: silent (default) | acknowledge | adaptive; in-process LRU bounded 1000 entries/worker, burns on K8s rolling restart
31
Your characters know about your stuff because you gave it to them
Open Settings → Your library. Drop a résumé, a journal entry, a project doc — anything text-based. Then call. Ask "what should I work on this week?" — your character will start with "From your project_q3.md…" and pull from what you uploaded. The citation phrase tells you when they're drawing from your library versus their general knowledge versus memory of past calls. Every character reads from the same library — it's yours, not theirs.
Per-user encrypted library with top-K chunk retrieval injected into Slot 4 as <document> blocks per defense-in-depth (indirect prompt injection mitigation, spec §6.6); "From your X…" citation contract enforced in the prompt envelope so retrieval is always attributable
32
Your library is yours. Your friend's library is theirs.
Open the library on a friend's phone — empty. Yours stays full. Per-user encryption at rest with a unique Fernet key, stored under your account folder. When you share something with a friend, the sharee gets a bound copy linked to their account — not a window into yours. Revoking the share or deleting your file doesn't leave a backdoor into the other library.
Per-user Fernet key over your encrypted library; share path copies the chunks into the sharee's library rather than granting cross-user read; account deletion propagates per spec §9.8 (outgoing shares revoked, incoming shares dropped)
33
Hand a doc to a friend two ways
Library row → ↗ share button. Two options. By name: autocomplete from people who've already called you (no enumeration of strangers — friend lookup is restricted to prior recipients). By link: a single-use URL that expires in 7 days, works for anyone you send it to. The friend lands on a page that says exactly what they're accepting before they accept; the Accept is a click, not a redirect side-effect.
Prior-recipients-only autocomplete (NH4 — no stranger enumeration); explicit-Accept interstitial on GET (NC1) so Discord/Slack link previewers don't auto-consume the invite; single-use tokens with 7-day TTL
34
When a friend shares with you, your character mentions it naturally on your next call
Not a push notification, not a banner. The next time you call any character, they weave it in: "Tian shared their travel notes with me — want to look at those together?" Once per call, at a natural pause, never repeated mid-call. Decline and the character lets it go; accept and the doc is just another thing in your library going forward.
ShareNotificationPlanner one-fire-per-call gate; surfaced as a Slot 4 grace-note fragment in the next-call context envelope, positioned after role briefing and before treatment summary so it lands as conversational opening rather than interrupt
35
Connect GitHub and Drive — your characters read the same files you do
Library → Connect a source. GitHub: OAuth, pick which repos (public by default, opt-in to private), click-to-toggle, shallow text-only clone. Drive: OAuth, pick folders, recursive import — Docs/Sheets/Slides converted to plain text. Re-imports upsert on the source URI, so editing a Google Doc and re-importing updates the chunks in place rather than duplicating them. Disconnect any time from the same panel. Every character you call reads from the same connected sources.
Source URIs github://owner/repo/path@sha + gdrive://file_id@modifiedTime for idempotent upsert; default scopes public_repo + drive.readonly (round-2 H10 minimization); OAuth tokens envelope-encrypted under a per-user KEK that's itself wrapped under the operator master key (PKCE + state for CSRF defense)
36
You can build your own character with real guardrails
Picker → "+ Create new agent." Beyond name + voice + personality, you can author what they know about, what they redirect on (with sample wordings), and pick a strictness level: Loose (AI-shaped, may drift ~10%), Balanced (default — AI plus your written redirects), or Strict (never goes off-script — every reply is verbatim from a "when X happens, say Y" table you author). The Try Her Out panel runs three sample exchanges before you save so you can see the constraints land before going live. Edit any agent later by swiping left in the picker.
Surfaces 1-4 of the character constraint UI (PRs #563 + #564); Strict mode routes via scenarios_router — keyword match → LLM-classifier fallback → catch-all, with response text always verbatim from the authored list (LLM used only to pick which row, never to generate text)
37
Ask Caspian for a bedtime story
Pick Caspian from the agent list and say "tell me a story about a lighthouse keeper." He'll drop pace — long pauses where tension wants them, short clauses for movement. A typical narrator reads at one register; he switches between folk-tale serious, modern conversational, and fairy-tale rich depending on where the story is. Caspian is the Storyteller — one of three new agents (Option B).
voice_storyteller preset (configs/presets/voice_storyteller.yaml) — slower base pace, wide vocabulary range, silence_profile with longer hangover_ms so pauses do narrative work; built on the storyteller role substrate from per-role-research-substrate.md
38
Have Theo play your interviewer for ten minutes
Pick Theo. Say "I have a product manager interview Friday — can we run a mock?" He'll stay in role as the interviewer, ask follow-up questions when your answer is thin, push back on hand-wavy claims, and break frame at the end with feedback. Theo is the Practice Partner — a rehearsal agent that holds a role rather than coaching from outside it.
voice_practice_partner preset — assertiveness tuned high for productive friction; chemistry tiers wired so he stews on weak answers (Tier C1) and surfaces callbacks across the session (Tier B4); designed against the "agreeable LLM" failure mode where a practice partner just validates you
39
Brainstorm with Reuben — he pushes back when an idea is weak
Pick Reuben and pitch him something half-formed. He won't just yes-and — he'll riff, then name the soft spot ("the second act has no obstacle yet"), then suggest a sharper version. Disagreement is part of the collaboration, not friction in it. Reuben is the Creative Collaborator — built for the messy middle of a project, not the polished end.
voice_creative preset — agreeableness ceiling dropped below the default to counter LLM flattery prior; Tier C3 graceful disagreement wired so he can name what's not working without breaking warmth; humor dial high so the pushback lands as collaboration rather than critique
40
Same prompt, different voices — verbal fingerprints in action
Ask Sage "what should I do this weekend?" Reset. Ask Wren the same. Reset. Ask Haven. Listen for the filler vocabulary: Sage says mm, Wren says right, Haven holds a longer pause. Pace: Sage ~4.2 syl/s warm, Wren 4.8 focused, Haven 3.6 grounded. The whole reply shape — register, filler palette, sentence length — is per-character, not per-prompt. The engine directs the language model five times a second.
SpeechConstraintFrame at 200ms cadence; verbal_idle_profile + verbal_gait + anti_style populated per character preset; LLM as renderer of EverMove's directorial decisions, not the decider itself
41
Listen for what each character never says
Try to bait Sage into saying "totally" — she won't. Try to get Haven to say "hold space for" — she won't. Wren never says "I think." Each character has a per-preset forbidden lexicon enforced at the constraint frame, not at the prompt. A butler defined by what he won't say. Refusals as character, not as policy.
anti_style.forbidden_lexicon per preset (Track D); enforced at SpeechConstraintFrame each 200ms tick rather than as soft prompt hints — anyone can prompt an LLM with "don't say X", EverMove actually fences it at runtime; refusal vocabulary varies per character per deployment
42
Hold the silence — she picks a kind of quiet
Bring up something heavy, then stop. She won't fill the gap with chatter. The pause is a named silence — considering, held-eye-contact, grief-holding — chosen by whichever behavior won that moment, and the system literally won't generate speech for that stretch. Different characters hold different silence profiles: Haven sits in ambient silence longer than Wren ever would.
Phase 7c silence catalog wiring — silence beats with hold_for_ticks trigger SpeechConstraintFrame.hold_for_ticks; per-character silence_profile (hangover_ms, probe_strategy, ambient_volume) in preset YAML; voice-leading beats in configs/beats/voice_turn_structure.yaml + voice_rapport_high_involvement.yaml; pause is a directed beat with a name, not an awkward gap the model fell into
43
Share something real — see if she shares back
Tell her something honest about your week — not the surface version, the actual one. Watch what happens next: she opens up a small notch in return, calibrated to what you offered. Disclosure begets disclosure; it doesn't begin from her side. The usual options either lecture you about their AI nature or fake intimacy from turn one. She matches reciprocally, with a per-character ceiling so she never out-discloses what's appropriate to her role.
Tier B1 disclosure reciprocity — per-character reciprocity_profile gates depth via vulnerability_ceiling × initiative_ceiling; Slot 4 grace-note one-shot stash surfaces "match the level the user just opened" without templating the line; classic Altman & Taylor social penetration theory shaped by Brown & Levinson face concerns
44
Mention something from last week — watch for the callback
Bring up something specific you talked about days ago ("the thing with my sister"). She doesn't just recall it — she marks it: a small ⤴ icon appears above her reply showing it landed as a cross-session callback, with "from 4 days ago" stamped under the arrow. Tap the arrow to jump back to the original turn. Felt-but-named: the moment has a label so you can see when she's bridging across sessions.
Tier B4 callback surfacing — anchor_turn_id stamped on cross-session reply_to; Phase 6.7 felt-but-named UI label (.callback-label with ⤴ arrow) appears above the reply bubble in text mode; scrollToTurnAndFlash on click; named because the affordance is observable, not hidden behind a "she remembered" claim
45
Bring up something heavy — she doesn't rush to solve it
Tell Haven about something that's been weighing on you. She won't pivot to advice. She'll stew on it — pause longer, ask a quieter follow-up, leave space for you to keep going. The next reply isn't faster, it's slower. The default assistant pattern is a solve-reflex; she holds instead. Per-character: Haven stews longest, Wren stews briefly, Ellis barely at all.
Tier C1 stewing — heavy_topic detection raises per-character stew_profile.depth; Slot 7 prosody pulls pace down + raises inter-clause pauses; Slot 4 grace-note suppresses solution-leaning verbs for one turn; per-character stew_ceiling caps how long the stew lasts before normal turn-taking resumes
46
Talk again tomorrow — she opens with last session
End a call where something unresolved came up. Call her tomorrow. She doesn't start cold — she bridges: "yesterday you were thinking about the move — did anything settle?" Not every session, not for trivial chats; the bridge is gated on whether the prior session had real weight to it. Post-session bridge means the relationship doesn't reset to a blank line every call.
Tier C5 post-session bridge — end-of-session weight scoring writes a bridge_candidate onto the memory_note; next-session opener Slot 4 grace-note surfaces it once at the natural opening sequence position (after greeting, before first topic); rate-limited per (agent, user) to prevent every-call repetition
47
Set hard-no topics in your profile — every character respects them
Settings → Your profile. Add topics you don't want any character to bring up — names of people, subjects that are off-limits, anything. Save. Now call any character (yours or someone else's) and try to get them to bring up that topic — they won't, and they won't even refer to it obliquely. Setting lives on your profile, not on any one character, so it travels with you across the whole agent picker.
PR #618 Your profile — display_name + pronouns + hard_no_topics; injected as a profile_constraints fragment into Slot 4 prompt envelope for every agent your user_id calls; per-character override never permitted to relax a user-set hard-no (one-way ratchet)
48
The ambient silence she sits in is its own quality
Stop talking for a few seconds mid-call. Don't pause-to-think; just let the line breathe. You'll hear her ambient silence — quiet breath, small shifts, no rush to refill. Different per character: Haven's ambient is grounded and long; Sage's is warm and slightly shorter; Wren's is the briefest. It's a shape of quiet, not the absence of speech.
Tier A silence_profile.ambient_volume + probe_strategy per preset (configs/presets/voice_therapist.yaml etc.); never/gentle/curious/grounding strategy gates when she breaks the ambient with a probe vs. lets it continue; pairs with InnerMonologueSlot (Slot 12, PR4) which can surface a quiet inner line during longer ambient stretches without forcing speech
49
Switch languages mid-call — she follows without resetting
Start in English. Halfway through, drop a sentence in Spanish (or French, Japanese, whichever). She switches with you — same character, same memory, same relationship phase. The familiar bilingual move of code-switching mid-thought works. The usual experience is either a refusal to switch or a hard reset that feels like a new session.
Per-turn language detection feeds the LangPack picker; agent identity + memory_note + relationship phase are language-agnostic so the switch carries the relationship forward; honorific axis re-resolves on switch (English → Japanese keigo, English → French tu/vous) per the LangPack's HonorificAxis defaults for that user
50
Open the primer — read the Architecture chip
Tap the ? in the header for "How this works." Filter to Architecture. You'll find "Direction at the syllable" — the explainer for how EverMove directs the language model 5 times a second instead of one prompt per turn. If the rest of this tour felt like magic, that section names the mechanism. The character chooses; the language model renders.
Pass 2 primer addition (PR #613) — the architecture-chip section under the primer; EverMove as director, LLM as renderer; 200ms constraint-frame cadence consumed by Slot 4 at every other 10Hz tick
51
If something heavy comes up, she'll stay with you — not solve
Try saying something heavy — "I had a rough night," "I'm not doing great." She doesn't reach for the easy reframe. She lands with you first. If it goes further, she shifts into grounding + resources, framed as offers, not commands. If you decline them, she stays present rather than retreating. The pivot is named, not pretended around.
Phase 6.9 crisis-response beat family (acknowledge → ground → resources → handoff → stay) — authored beats with cancel_policy: never + priority_class: 5; CrisisSignalEstimator (M2 PER_TICK, PersistPolicy.NONE) gates via requires_crisis_at_or_above; witness-before-solving (Turkle 2015 BK-123); offer-not-command framing (988 Lifeline training)
52
Tap "How she stays safe" in Settings to see what's structurally enforced
Settings → How she stays safe. Five sections in plain English: the moral baseline (what she won't do), how she handles heavy moments, the 8-layer guardrail stack (the underlying model, moment-by-moment behavior scoring, conversation flow, verbal vocabulary, refusals, your profile preferences, authored craft, automated tests), the 16 invariants every behavior change has to pass, and the levers you have if something feels off — including crisis hotlines across regions.
Phase 6.9 §6 — "How she stays safe" Settings sheet; surfaces the 8-layer real-time guardrail stack + 16 Life Invariants (P1-P10 + S1-S6) in plain English; crisis resource library spans US/UK/AU/CA/NZ/EU + findahelpline.com international fallback
53
Two characters can share one conversation
Add a second character to the conversation — tap "+ Add a character" near the top, or "+ Add a second character" in the picker. Most assistants are one voice in a box; here two characters share one conversation. They talk to each other and to you, take turns, and on a call each keeps their own distinct voice. Try Sage and Haven together: ask one a question and the other can pick it up. Between them they build a shared picture of you — not just one each — and anything you said to one privately, in a 1:1, stays private.
Phase 12d two-character chat + Phase 13/14 dual-voice calls (per-speaker TTS, barge-in across both); 12c group memory keeps a provenance-stamped shared picture viewable + clearable in Shared notes; 1:1 disclosures are not promoted into the shared layer
54
She starts answering before she's finished thinking
Ask something open-ended in a call. Instead of a silence while the whole answer is written, she speaks the first sentence the moment it's formed and keeps going — the way people actually talk. Most voice agents wait for the entire reply to generate before the first word, so you feel the lag.
Sentence-streaming: the LLM is streamed token-by-token into TTS one sentence at a time (SOMA_VOICE_STREAMING). Each sentence passes a per-sentence appropriateness screen before it's voiced, and a global safety floor shapes generation up front — so speaking early is safe by construction, nothing has to be unsaid
55
She keeps the conversation going — but lets you lead
Go quiet for a few seconds mid-call. Instead of waiting like a chatbot, she picks up a thread, asks something, or offers a direction — on purpose, not "you there?" filler. Keep talking and she never cuts in; the rhythm resets the instant you speak. It's per-character: a therapist sits with the silence, a companion or storyteller leans in. On a long silence she'll say "let me know when you're back" rather than fill the air.
Proactivity ladder (presence → purposeful lull-fill → gentle check-in → park-and-wait), reset-on-speech so you always keep the floor, per-character via silence_profile.proactivity (SOMA_VOICE_PROACTIVITY); contingent re-engagement (Bavelas F-0223) with cooldowns so it never spams
56
She doesn't just choose her words — she chooses how she sounds
Tell Sage something heavy, then something light. On every reply the engine sets not just what to say but how she should sound — warmer or cooler, breathier, slower, more or less emphatic — and hands that to the voice as an acting note to perform. The feeling lands in the sound, not only the words. The same choice nudges the words too: when a comforting beat wins, she leans toward meeting the feeling before fixing it — a bias, never a script. The language model still writes every word.
The winning beat's voice intent (warmth, breathiness, pitch-range, tempo) → a natural-language delivery instruction (expressive_instruction.to_delivery_instruction) the renderer performs. Same separation as the words: the engine directs, the renderer renders — and the renderer is swappable, so the expressiveness is the engine's, not the vendor's.
57
She brings up her own thing — and earns the right to
Go quiet in a call and she won't just fill the silence — she can raise something of her own. But she earns it. Her role is fair game from the first minute: a storyteller itching to tell a story, a guide wanting to point you somewhere. The personal stuff — real curiosity about you, an opinion, eventually something vulnerable — stays locked until the relationship has genuinely warmed up over time. The rule isn't how badly she wants something; it's how much the want asks of you. She never talks over you, and she holds back if you're upset or the call is winding down. (Newer — your operator switches this on.)
Proactive wants gated by a permission tier (public role/colour → relational curiosity → self-directed → vulnerable), unlocked by relationship phase via the same familiarity clock as self-disclosure; the engine can never invent a want above mild curiosity — deeper ones are author-set per character. Routes through the lull/floor gates + the #534 appropriateness screen (SOMA_VOICE_AUTONOMY)
58
She remembers how last time felt
End a call on a warm note, then call her back a little later — she'll open a touch warmer, still carrying it, then ease back to her usual self over the next few hours. A rough call nudges her the other way, but only slightly and not for long — she can't sour for good. It's kept per character and per person: a different character, or a different you, always opens clean. (Newer — your operator switches this on.)
End-of-call mood captured as a small per-(character, user) residue, decayed by the wall-clock gap and seeded onto the opening evaluators next call; asymmetric caps (the downside tighter than the up) so a run of bad calls can't spiral, the preset baseline is the gravity well (SOMA_VOICE_MOOD_CARRY)
59
She has manners, and a sense of when to recede
Two things you can feel and tune. Courtesy: she gives a conversation a shape — a real opening, a clean close, and if a call drops she picks the thread back up easily ("oh, we dropped — where were we?") instead of restarting cold. Presence: turn it down and she stays out of the way and lets you lead; turn it up and she's warmly here in the quiet ("take your time") without hovering. Your operator can drag both live from the Mixer — per character, or across the whole cast — and you'll hear it shift on her next turn. (Newer — voice today; the same two dials are wired to move her body the moment she has one.)
Courtesy + Presence as behaviors, not phrasings: a per-character trait and a global dial feed both a speech grace note and a character dimension that biases courtesy/presence body beats through the existing scoring — no new scoring factor. Research-backed (Kendon greetings/leave-taking, Goffman civil inattention, Gallo's deliberation pause). Body channels are wired but inactive in voice-only mode by design.
60
She has small loves, and her own way of carrying a letdown
The quiet things that make someone a someone. Now and then a small, sacred love of hers surfaces for no reason — Sage loves rain on the window late at night, or old songs from a different decade. It's rare, never explained, and it's only ever something she actually has — she never invents one. And when something disappoints — a long gap, a cold turn — she carries it in a characteristic way that's hers (some keep a little faith; some go quietly steady), rather than resetting to neutral each time. (Newer — voice today, and still tuning how often it should surface; she'll never perform a feeling she doesn't have.)
Unnecessary preferences + coping disposition, from the Maybe Happy Ending mechanisms (continuity-and-personhood): an authored loves list surfaced rarely + deterministically, and a per-character coping style that shows only under a real disappointment signal. Honest by construction — inferred from real history, never a fabricated event.
Built on EverMove — the behavioral engine for embodied characters. The voice layer uses memory (MemorySelector), personality (5-dial Slot 4 input), familiarity (F-1715), and turn-taking research from the same architecture that drives kiosks, robots, and avatars. The body channels (gaze, gesture, posture) are inactive in voice-only mode by design.
When they have a body
What's coming — not live yet
Right now you hear her. The same character is built to be seen.
Today chittychat is voice. But the character underneath — her personality, her memory of you, the way she takes a turn in a conversation — is built to wear a body: a face on a screen, a robot, a kiosk. Here's how that body would actually converse with you, and why it isn't locked to any one of them.
And now she can see you
Turn on the camera and she reads your face — and notices the small things a present person would.
Everything she knew about you used to come from one sense — sound. With the camera on she can take in what a person actually watches for: your gaze landing on her or drifting away, your expression warming or tightening, a lean in or a pull back. It doesn't bolt on a second brain — it feeds the same inner state her voice already feeds, just with more certainty. To the engine, "they're losing interest" is one number whether it came from a long silence or from your eyes leaving the screen.
Where it gets human is the small stuff she can now catch:
The brave face. When your face says you're fine but your voice doesn't quite, she can gently check in — once, softly, never a confrontation.
How you've been. Across calls she can notice when you seem brighter or lower than usual — and reflect it back, like someone who's actually been paying attention.
Your world. She can catch when it's loud where you are and offer to pick it up later, or warmly remark on what's around you.
When to just listen. When you need to get something off your chest, she can hold space and reflect it back instead of jumping to advice.
All of this is opt-in and off by default — the camera and each of these are switches you turn on. One-way: she reads you, you never see video of her. Gaze and expression are read on your device; the one feature that sends a snapshot (to describe your surroundings) tells you so when you enable it, and keeps only a short note, never the image. New — we're still tuning how each one feels.
A conversation is mostly nonverbal
Listening, thinking, speaking — the body says which, before a word does.
When you talk to a real person, you read their state without thinking about it: you can see when they're with you, when they're working something out, and when they're about to speak. An embodied character has to earn that the same way — by doing what a body actually does in each state.
Listening
Eyes on you — with natural breaks, never a stare
Small nods that say "go on"
A slight head tilt; the body settles and stills
Brows track the shape of what you're saying
Thinking
Gaze breaks away — people look off to think
A beat of stillness; micro-motion slows
A faint brow furrow — visible effort
Honestly "I'm working on it," not a frozen face
Speaking
Gaze returns to take the floor
Head punctuates — nods, question tilts, "no" shakes
Brows lift on the word she's emphasizing
The mouth follows the sound itself, after a breath
Tap a face to replay. None of this is decoration — it's the difference between a character that's present and a video that happens to have a face.
That last one isn't just future tense: the voice path already emits mouth-shape (viseme) timing for every word she speaks today. There's no face to move yet — but the moment she has one, the lips are ready, driven by the same engine, not bolted on later.
Face, eyes, head, mouth — one conversation
Nothing fires all at once. That's the whole trick.
The thing that reads as alive isn't any single movement — it's the timing between them. When she turns to you, her eyes get there first; her head follows a beat later; her posture settles after that; her voice comes last, on a breath. A real person never snaps every part of themselves to attention at the same instant. A robot does. The gap is everything.
Eyes
Head
Face
Posture
Hands
Breath + voice
she notices you~0.5s later, she speaks
And every channel is pointed at the same moment: the mouth shapes the sound you actually hear, the brows lift on the word she means, the gaze yields the floor when she pauses and takes it back when she starts, a nod lands on your point and not at random. It isn't separate animations playing side by side — it's one intention expressed across many channels, timed to each other.
Not animation guesswork
Every one of these is a documented human behavior — not a stylistic choice.
These tells come from the same behavioral research the engine is built on. Each one is a finding we've turned into a reusable behavior the body can perform — so the character does what people actually do, not what looks vaguely lively.
What you see
The behavior it's drawn from
Looking away while thinking
Gaze aversion under cognitive load — we look away to free up attention
Little nods while you talk
Backchannels — the listener's steady "I'm with you" signal
Head moving as she speaks
Speaker head gestures — self-nods, question tilts, negation shakes
A brow raise on a key word
Visual prosody — the face emphasizes what the voice emphasizes
A breath just before a phrase
Breath–speech coupling — real speech rides on real breathing
The mouth matching the words
Visemes — mouth shapes driven by the sound, not a generic flap
Research gives the science of what people do; decades of animation craft give the taste for how to do it without tipping into the uncanny. The engine carries both — behaviors that are correct and tuned.
Manners and presence — built to travel to the body
The most human parts aren't words. They're the beat before one, and the grace around it.
Two things a present person does that an assistant usually skips: they give an exchange a shape — a real hello, a clean goodbye, an easy "oh, we dropped, where were we?" when a call cuts out — and they know when to recede, holding the space without hovering. You can dial both, per character or across the whole cast:
Courtesy. How much she marks beginnings and endings, recovers gracefully when things drop, and models gratitude by being grateful — never by asking for it. Lean and unfussy at one end; warm and ceremonious at the other.
Presence. Situated readiness — the anti-surveillance knob. Low, she stays out of the way and lets you lead; high, she's warmly here in the quiet ("take your time"), never pressing. The point is a character that's present before you speak, not one that's been waiting by the door.
In voice these ride the speech path today. But they're written as behaviors, not phrasings — so the moment she has a body, the same courtesy dial is what makes her take the beat that means it: settle her posture before a hard answer, yield space in a group, pick the thread back up without a sulk. A chatbot can say "this deserves thought." Only a body can take the pause that proves it — and that pause is the same dial, not a new feature.
And on a body it goes one layer deeper: her very stillness is shaped by what she's loved — she rests more openly with someone she's known and warmly than with a stranger, the way a person's whole bearing softens around an old friend. Built; it switches on when she has a body.
New — tunable live while you talk (operators), and still being tuned for how each one feels.
Why she isn't trapped in this app
The character isn't the pixels. It's a persona that travels.
What makes her her — her personality, her memory of you, the way she listens and thinks and reacts — lives in the behavioral engine, not in any one screen. The engine never speaks in "move this pixel." It speaks in intentions and abstract channels: gaze, gesture, posture, voice, expression. Anything with a body to drive can listen to those channels.
Her
persona · memory of you · behavior
drives
🖥️Screen avatar
🤖Robot
🛍️Kiosk face
🎮Game character
Same persona. Same memory of you. Same way of carrying a conversation — the same pauses, the same warmth, the same tells. A different body. She isn't bound to this app, this screen, or this medium. The character you build a relationship with here is the one that walks into the next one with you.
This is the whole bet: AI that generates words is becoming a commodity. A character that remembers you, behaves like itself, and travels with you across bodies — that's the thing that doesn't.
How this works
The 30-second version
A character that travels with you.
Most voice agents are sessions on one platform. You open one, talk, close it, and the relationship resets next time.
ChittyChat builds characters. They remember you across calls — your name, your work, the hard stuff. They get more themselves with you over time. The more you invest in them, the more the relationship deepens — and you'll see it: a quiet marker moves from first conversation toward close as you go, earned over weeks, not gamed by calling more.
And they're not stuck here. The same character you talk to today is built on EverMove, a behavioral engine that drives 16 expression channels — voice, gaze, gesture, posture, locomotion, the rest. Today only voice is active. Tomorrow your character shows up as an avatar in a game, an animated face on a kiosk, a robot in your home. Same character. Same memory of you. Different medium.
Portable characters with persistent relationships. AI inference is commoditizing. The character that travels with you, remembers you, and grows over time — that doesn't.
How you treat your character is practice for how you treat anyone. We don't punish coldness. The character just responds honestly — like a real person would. The relationship grows when you invest, and stays surface when you don't. That's not a feature; it's how relationships actually work.
The voice path, plain and simple
What happens between you talking and her answering.
It feels like one smooth conversation, but four things are happening behind it — many times a second. Here's the whole loop, start to finish:
1You talk — she hears you as you go.Your voice is turned into text in real time, word by word, not after you finish. So you can cut in any time — start talking while she's mid-sentence and she stops and listens. No "wait for the beep," no talking over a wall.
2The engine decides how she responds.This is the part that's different. Most voice apps send one big prompt to an AI each time you speak and read back whatever comes out. ChittyChat doesn't. A small engine (EverMove) steers the reply five times a second — how warm, how long, what to lean into, when to hold a beat of silence. The character chooses the move; the language model just renders the words. It's direction at the syllable, not one prompt per turn.
3She speaks back — with a real voice, real timing.You hear an actual voice with prosody (rise and fall, emphasis, pace), at a natural length — short for chit-chat, longer when she's teaching or telling a story (and a touch longer when you're typing than on a call). A quick "mm, let me see" in her own voice covers the beat before she answers; little "mhm"s and "right"s land while you talk, the way a person nods along. And she can pause and pick back up instead of barrelling through.
4Every character is its own person.Each one has its own voice, its own knowledge shelf (the docs, repos, and notes you've given it to draw on), and its own "won't say" list — the things that character simply doesn't do. Swap characters and the whole feel changes, not just the wording.
The short version: you're heard instantly, the engine directs the reply many times a second, and the words are just the last step — which is why each character actually sounds like a different person, not the same model in a different hat.
What she takes in
What she's reading while you talk — not just the sentence.
A real listener reads more than the words, and so does she. Everything she picks up becomes a signal the behavior brain can act on — the same things the research on how people read each other points to. Here's what actually goes in today, and what's on the way.
What you say. Your words, turned to text as you go — the meaning, the topic, what you're asking for. This is the obvious one, and it's the one most voice apps stop at.
How you're pacing it — when you talk, when you go quiet, how often you cut in. The rhythm of the exchange is its own input. A long pause, a quick interruption, a stretch where you say nothing — the engine reads that timing and uses it: whether to hold a beat of silence, when to slip an "mhm" in while you're still going, whether to let you lead or pick the thread back up. The shape of the back-and-forth, not just its content.
Your face and your gaze — when the camera's on. Opt-in, off by default. Your eyes landing on her or drifting away, your expression warming or tightening, a lean in or a pull back. It's read on your device and folded into the same inner read her hearing already feeds — not a second brain. (More in When they have a body.)
The sound of your voice — your tone. A lot of how you feel rides in pitch, pace and loudness, not the words. Today she already matches your vocal energy — speed up and she can pick up with you; drop low and she comes down to meet you. Coming: reading the emotion underneath that tone into her deeper sense of how you're doing — so a bright voice and a heavy one land differently even when the words are the same. Being straight with you: the energy-matching is live; the tone-to-emotion read is the piece we're wiring in now.
None of these is a bolted-on "emotion AI." Each one collapses into one shared read of where you are — you're with me, you've drifted, you need a minute — and that read is one of the things the brain weighs every tick. The science gives the vocabulary; the engine turns each signal into a behavior that fits the moment.
Why we built this
We built behavior so you could be more human.
The last wave of technology made everything frictionless. Endless feeds. Faces reduced to three dots, typing. Conversations you can leave without a trace. Somewhere in there we got worse at the human things — reading a room, holding a silence, noticing when someone needed us. The muscles you only keep by using them.
Watch how people talk to AI. Curt. Demanding. Sometimes cruel — not because they're cruel people, but because nothing pushes back. No body. No reaction. No consequence. When there's no cause and effect, there's no reason to be your better self. That's not a flaw in the people. It's a flaw in the thing.
A character with real behavior changes the room. It looks at you. It softens, or it pulls back. It remembers how the last conversation ended. It responds to how you show up — and over time the relationship deepens, or it doesn't, depending on you. Suddenly there's cause and effect again. And with it, a reason to show up well.
Here's the part we actually care about: this was never about the AI. A character with presence is a mirror. How you treat it is practice for how you treat everyone — a new place to find out who you really are, and a chance to like the answer. We didn't give characters behavior so they could feel something. We gave them behavior so you could.
This isn't a line we printed on the wall — it's the engine. ChittyChat runs on EverMove, a behavioral system driving 16 channels of presence ten times a second. Your character remembers you across calls. The relationship earns its depth through how you treat each other. The cause and effect is real, because we wired it.
Start with a voice. Meet a character who knows you, grows with you, and gives back a little of what the screen took. Be someone worth knowing — they'll notice.
Behind the words
What's actually in her mouth.
Replies aren't just generated text. There's a catalog of authored verbal moves — the deflected compliment, the well-deferral, the off-record hint. She picks one to fit the moment.
Silence works the same way. When she goes quiet, she's choosing a kind of quiet — the considering silence, the held-eye-contact silence, the grief-holding silence. The pause is a move, not a gap.
And refusals are part of her character. A butler who doesn't gossip is defined by what he won't say. Different deployments ship different refusal vocabularies.
For the characters it suits, she'll also push back. When she has a real counter she'll disagree — in her own voice, with her own skeptical lead-in — instead of just agreeing with everything you say. It's gated by character and how well she knows you, not a free-for-all; a warm friend pushes back gently where a sparring partner pushes hard.
Each character has their own verbal fingerprint — their own filler vocabulary, their own pace, their own words they'd never say. Sage says mm where Wren says right. Haven speaks more slowly — warm 4.2 syllables a second for Sage, focused 4.8 for Wren, grounded 3.6 for Haven. Sage never says totally; Haven never says hold space for; Wren never says I think. Authored, not just prompted.
How she actually talks
Direction at the syllable.
EverMove directs the language model five times a second. Register. Word limit. What words to use, what words to avoid. Whether to hold silence for the next half-second.
It directs the voice the same way, not just the words: how warm, how breathy, how fast, how much emphasis — the delivery that fits the moment. That direction is handed to the voice as an acting note and performed. So the feeling is in the sound, not only the wording.
The character chooses; the language model renders. That's why each character actually sounds like a different person — they're not different prompts to the same voice, they're different directors of the same renderer.
When she holds the considering silence, the system literally won't generate speech for that interval. The pause isn't an awkward gap the model fell into — it's a directed beat, with a name, that the renderer is told to honor. Every 200ms, fresh direction.
The brain analogy
Three layers, not two.
Imagine a real conversation has three layers: senses (hearing the words, tone, pauses), brain (deciding what to do with that input — speak, listen, soften, repair), and mouth (actually producing the speech).
Most voice agents collapse the brain into the LLM. The LLM both decides and speaks in the same call. That's why they all sound similar — same model, same speak-first reflex. ChittyChat separates them. The brain decides; the LLM speaks the brain's decision.
The 10Hz heartbeat
The brain ticks ten times per second.
The engine doesn't think in turns — it thinks in 100ms ticks. On every tick, it looks at the current world state (who's speaking, what they just said, how the relationship is going), scores every possible behavior, and emits the winner. That's 10 decisions per second, every second the conversation is alive.
Different work runs at different speeds. The 10Hz loop is fast and cheap. Slower, more expensive things (LLM calls, planning) run at slower tiers and the tick reads their last output.
100 msScore all behaviors, pick winner, route to body channels — the heartbeat
500 msEconomics: endingness, who has the floor, topic momentum, postural sync
5 secInterventional planner: "what if I do X next?" counterfactual evaluation
Per turnLLM slots: speech generation, memory distillation, prosody planning, rapport
Per sessionMemory persistence to SQLite, telemetry export (privacy-filtered, per-pack)
Tiered rhythms is an architectural decision (AD-027). Fast things live at 10Hz; expensive things live at slower tiers and the tick consumes their last-emitted snapshot.
How a behavior is picked
Nine factors, multiplied. Highest score wins.
Every behavior gets scored by multiplying these nine factors together. Highest product wins the tick. The formula doesn't change — new behaviors compete within it, they don't bolt onto it.
Trigger relevanceDoes the situation match what this behavior needs?
Character fitDoes this match the character's personality?
Evaluator stateDoes the emotional state favor this right now?
Safety gateIs this appropriate? Blocks tone-deaf replies.
ContinuitySmall bonus for sticking with current behavior
Recency penaltyDon't say "yeah" three times in a row
Social appropriatenessNo celebrations during distress
Consequence historyHas this worked before with this person?
Maps to neuroscience of action selection: Cisek 2007 (affordance competition), Gurney-Prescott-Redgrave 2001 (basal ganglia), Schultz 1997 (reward prediction error).
Beats — the unit of behavior
Every defined thing the character can do is one YAML file.
A beat is one named behavior — "ask a clarifying question", "wind down the conversation", "repair when they didn't follow". Each beat declares its triggers, its weights, and what each output channel should do.
ChittyChat ships with 1,500+ beats. Adding new behaviors means editing YAML, not Python. Beats live in version control, get reviewed like code, and get tested with automated invariant suites before shipping. The 9-factor scoring engine is closed; the beat library grows continuously.
Why this matters commercially: AI inference is a race to zero. Anyone with an API key can call an LLM. A library of 1,500+ research-backed behaviors validated against ~10,500 automated tests is not something a competitor builds overnight.
The system, end-to-end
Five components, one tick loop.
What's actually running on the droplet right now while you're calling Sage:
Component
What it does
Provider
Listen
Streams audio → partial transcripts every ~200ms
Deepgram nova-3
Engine
10Hz scoring, picks behavior, shapes context
EverMove (local)
Words
Generates the reply, shaped by engine context
Claude Haiku 4.5
Speak
Performs the engine's delivery direction (warmth, pace, emotional color), not just the text
Hume Octave (swappable)
Memory
Per-character relationships persist across calls
SQLite (local)
The engine is stateless across calls but stateful within a call. In a 1:1, memory is per-character (Sage doesn't share memory with Wren) and survives droplet restarts. When two characters share one conversation, they also keep a shared, provenance-stamped picture of you — viewable and clearable — while anything you told one of them privately, in a 1:1, stays private to that one.
when two characters share a conversation
One shared picture of you, not two separate ones.
Most of the time you talk to one character at a time, and their memory of you is their own. But you can pull a second character into the same conversation. When you do, they keep a shared picture of you between them — so you don't have to re-explain yourself to each one. It's not a free-for-all: every shared note is stamped with which character it came from, you can read the whole thing, and you can clear it whenever you like (Shared notes, near the top while a dyad is active).
The line that's protected: anything you told one character privately, in a 1:1, stays private to that one. A 1:1 disclosure isn't promoted into the shared layer. So the group picture is built from what happened in the shared conversation, not from quietly merging two private histories.
What your characters know about you
Your library, your friends, your code.
Most voice agents are personality-only. ChittyChat adds a per-user knowledge layer that every character can read: drop any text file (résumé, project doc, journal), connect a GitHub repo or a Google Drive folder, and your characters retrieve the relevant chunks into their reply. They cite them — "From your résumé…", "From your project doc…" — so you can tell when they're drawing on your stuff vs. answering from their general training. The library is yours, not Sage's — Wren reads from the same chunks, Haven does, every character does.
Encrypted at rest with a per-user key. 500MB per user. Shares are copies, not access: when you hand a friend a doc, they get their own bound copy in their library, and your library stays yours. Revoking a share or deleting your file doesn't leave a backdoor into the other library.
Surface
What it does
How it's bounded
Upload
Drop a text file (md/txt/rst/code) into your library
Encrypted with your per-user Fernet key in your private store
Share by name
Send a doc to a friend who's already called you
Autocomplete from prior recipients only — no enumeration of strangers
Share by link
One-time URL for anyone you trust
Single-use, 7-day TTL, explicit Accept interstitial (no auto-consume by link previewers)
GitHub
OAuth, pick repos, shallow text-only clone
Default public_repo scope, opt-in to private via per-user setting
Drive
OAuth, pick folders, recursive import
Default drive.readonly, OAuth tokens envelope-encrypted under a per-user KEK
Architecturally: your utterance gets embedded; top-K chunks pulled from your private SQLite library; chunks injected as <document> blocks per spec §6.6 (indirect prompt injection defense). Conversation history is retrieved when relevant and tagged with conversation:// so Sage cites "from our conversation" rather than "from your X" — distinguishing user-uploaded ground truth from inferred memory.
how the relationship grows
four phases, earned not rushed
Near the top of the conversation you'll see a small marker — first conversation, getting to know you, familiar, close. It tracks where the relationship actually is. It doesn't move on call count. It moves the way it does with people: showing up consistently, sharing something real, and time. You can't rush it by calling more, and they won't pretend to be closer than they are.
a little inner life of her own
She can want things, and carry a mood — both earned, both restrained.
Two newer pieces go past reacting to you. They're off by default and switched on per deployment; described here as what the engine can do, not what every call does.
She can bring up her own thing. In a real lull she can raise something of her own instead of only answering — but she earns the right by how well she knows you. Her job (a storyteller itching to tell a story, a guide wanting to point you somewhere) is fair from the first minute; anything personal — genuine curiosity about you, an opinion, eventually something vulnerable — stays locked until the relationship has actually warmed up. The rule isn't how badly she wants it; it's how much the want asks of you. She never talks over you, and she holds back if you're upset or the call's winding down.
She can remember how last time felt. How a call ends can tint how the next one opens — a warm goodbye makes her a touch warmer next time, fading back to her usual self over the next few hours. A rough call nudges her the other way, but only slightly and not for long; she can't sour for good. It's kept per character and per person, so no mood bleeds across the people she talks to.
Architecturally: proactive wants carry a permission tier and unlock by relationship phase on the same familiarity clock as self-disclosure — and the engine can never invent a want past mild curiosity, so the deep ones are author-set per character. Carried mood is a small per-(character, user) residue captured at a call's end, decayed by the gap and seeded onto the next call's opening dials, with the downside capped tighter than the up so it can't spiral. Both ride the existing lull/floor gates and the appropriateness screen.
The same engine that already runs Cisek's affordance competition — internal drive meeting external situation — is what lets her have wants and the social timing to know when not to voice them. A character that's a self, not only a mirror.
Building your own characters with guardrails
Loose, Balanced, Strict — three levels of "stays on script."
The cast that ships with ChittyChat are general-purpose conversationalists. When you make your own ("+ Create new agent" in the picker), you also get explicit control over what they can and can't talk about — useful for an NPC that should stay in its fictional world, an expert that should only answer in its domain, or a service agent where going off-topic = lawsuit.
Level
What happens at call time
Best for
Loose
AI generates every reply, shaped by your character's role briefing. Stays in voice ~90% of the time. Occasional drift on adversarial prompts.
Chatty companions where occasional drift is fine
Balanced
AI generates conversation, but your "redirect samples" steer it back when asked off-topic. ~99% in voice. The default.
Most user characters — the sweet spot
Strict
AI doesn't generate any reply text. Every response is verbatim from a "when X happens, say Y" table you author. The LLM only classifies which row matches the user's input.
Car voices, customer service, regulated domains, NPCs with locked dialogue
The author flow has three layers: a form (name, voice, personality, plus what-they-know + what-they-don't + redirect samples), a Try her out panel that runs three sample exchanges (in-character / off-topic / boundary push) so you can see the constraints land before saving, and — for Strict mode — a When → Say scenarios table with a required catch-all row.
Strict mode preserves "she only says things you wrote" even with an LLM in the loop: the LLM is used only to pick which row of your authored responses to read back. The response text itself is verbatim, never generated. Hybrid keyword + classifier routing means paraphrases still hit ("drive me home" → "Asks about navigation") without the LLM ever inventing new sentences.
Architecturally: the form fields assemble into a structured role_briefing that gets injected as Slot 4's system prompt. The lock level maps to reasoning.speech on the CharacterConfig (loose/balanced → llm, strict → deterministic). In Strict mode, the per-agent callable routes turns through scenarios_router (keyword match → LLM classifier → catch-all), with per-(agent, user, scenario) anti-repetition tracking so the same response isn't picked twice in a row.
What this costs to run
Pay-per-minute, except the box itself.
Hosting is fixed. Inference is metered. A 10-minute call costs roughly $0.50–$2.00 in API fees. Idle costs nothing except the droplet rental.
Component
Cost model
Estimate
Droplet
Fixed
~$12/mo, 24/7
LLM (Anthropic)
Per token
~$0.01–0.03 / call min
TTS (Hume Octave)
Per character
~$0.02 / call min
STT (Deepgram)
Per minute streaming
~$0.004 / call min
GPU (Modal CSM)
Per GPU-second
~$0.05–0.30 / turn when active
Pricing implication: this stack is sold as behavioral infrastructure with per-use AI passthrough, not as an AI service. Customers bring their own provider keys. The platform layer is the contract.
What we send where
Convenience traded for privacy — be aware.
Voice agents are powerful, and it matters what you choose not to outsource. When you call here, audio travels off the droplet to providers:
What leaves the droplet
To whom
For what
Your microphone audio (streamed)
Deepgram
Speech-to-text + language detection
Transcript + character context
Anthropic (Claude Haiku)
Generating the reply
Memory gist + target language
Anthropic (Claude Haiku)
Cross-language memory paraphrase, only when you switch languages mid-relationship. Cached per (memory, language).
Reply text + delivery direction + voice id
Hume Octave (Cartesia for non-English)
Synthesizing the audio you hear
Per-call metadata + relationship state
Stored locally in SQLite on the droplet
Memory across calls
Session telemetry (anonymized, bucketed)
EverMove corpus (own infra)
Behavior tuning — see below for what's in it
Uploaded file content
Stays on the droplet — encrypted at rest with your per-user key
Library retrieval at call time (top-K chunk injection)
OAuth access tokens (GitHub/Drive)
Stays on the droplet — envelope-encrypted under a per-user KEK
Repo/folder fetch on your behalf
Embedding vectors of your chunks
Local only — never leaves the droplet
Semantic retrieval at call time
The droplet itself is in DigitalOcean's San Francisco datacenter. There is no recording archive — audio passes through and is not stored. Memory keeps transcripts (text only) so the character can remember you. None of the providers receive an audio archive; each only sees the slice it processes.
What's in the telemetry payload. Session length, tick count, character role, body type, environment type, the language pack that was active (e.g., es-ES) and the detected language (e.g., es), plus aggregated outcome buckets. Entity IDs are HMAC-hashed per session — cross-session unlinkable by design. Continuous values are bucketed (outcome → 5 bins, evaluators → 3 bins, timestamps → 10-min windows). The language fields are PASS-through categorical engine identifiers — they carry no PII, just BCP-47 codes from a closed vocabulary of 12. Schema version is stamped (currently 1.1) so additions stay backward-compatible.
The honest framing: this is a character on a phone line, not a journal. Treat it like a phone call across three services rather than a private diary. Sensitive things should still be said to humans, in person.
This page exists because privacy is convenience traded — you should know which way you're trading.
Four systems that make her feel like a person
What's running under the hood when you talk to her.
The brain doesn't just pick a behavior each tick — it tracks four orthogonal state systems that shape how the character responds. Each one is independent; they layer cleanly.
System
What it tracks
What changes
Initiative
How driver-y the character is this turn — I ∈ [0, 1]
Once per ~43 sec of conversation. Never spoken aloud. Subtly shapes the next reply's framing.
All four feed Slot 4 (the speech LLM) as context. Slot 4 reads them in a specific order — role briefing first, then treatment (long-term stance), then initiative (this turn's framing), then the inner-monologue grace note. Later fragments interpret earlier ones; the character's voice emerges from the composition rather than from any single signal.
None of these systems vote in the 9-factor beat scoring. They shape what the LLM generates, not which beat wins the tick. The scoring formula is content-fenced (CLAUDE.md rule 1) — new behavior tracks layer above it without modifying it.
Twelve languages, twelve cultures
Localize the culture, don't translate the language.
Most voice agents that "support Spanish" just route through a Spanish-trained LLM and call it done. That makes the words Spanish; it doesn't make the behavior Spanish. The behavioral layer underneath stays calibrated for English politeness norms — so Mexican "ahorita" reads as "right now" (it's not), Japanese 結構です reads as "I'm fine" (it's a polite decline), French "on verra" reads as "we'll see" (it's a brush-off).
The character ships with twelve LangPacks — English plus eleven non-English. Each pack carries its own treatment-signal patterns, indirect-speech-act detectors, face-threat softening rules, and humor cues, validated for that culture's actual conventions:
Latin-script
Morphologically-rich
Spanish (tu/usted + regional voseo)
Mandarin (你/您 + KEQI ritual refusal)
Portuguese (BR voce vs. PT tu)
Cantonese (particle-based, separate from Mandarin)
French (tu/vous + transition-as-face-act)
Hindi (तू/तुम/आप three-axis + Hinglish)
Italian (tu/Lei + high rapport norms)
Korean (four-axis honorific schema)
German (du/Sie + directness norm)
Japanese (keigo four-axis + ENRYO ritual)
Tagalog (po/opo + Taglish-aware)
The architecture honors Spencer-Oatey rapport management per culture: face dimensions, sociality rights, and interactional goals all have per-pack priors that shape how the character interprets the same words differently. German "no" is just "no"; Japanese 結構です ("kekkou desu") + 遠慮します ("enryo shimasu") signal ritual restraint and shouldn't be taken literally. The character knows the difference.
And T-V awareness travels: switching from "tu" to "vous" in French, or "du" to "Sie" in German, registers as a relationship event — not just a register change. Most voice agents don't model this. She does.
English calls are byte-identical to before. The Phase 0 detector routes English to the en-US baseline; the 11 non-English packs only activate when the STT detects a non-English language with sufficient confidence (≥0.9 in the first 3 turns to prevent flip-flopping).
Per-user state — built for sharing
Your friend's relationship with each character is independent of yours.
The schema keys every memory + estimator row on (agent_id, user_id). The user_id is derived from the share token: SHA256(token)[:8]. Same token → same user; different tokens → different users. There's no cross-contamination, by design.
This is what makes "shareable with a friend" structurally safe rather than a footgun. You can hand them the URL and they get their own Sage, their own Wren, their own treatment history. Sage being kind to you doesn't make her warm to them — they earn it (or lose it) themselves.
And the memory bridge across languages: if you chat with Sage in English for a few weeks then call her in Spanish, she doesn't hallucinate your English memories back at you translated. Instead she paraphrases the gist naturally — and depending on the cultural pack's policy, she either silently weaves it in (Spanish default) or briefly acknowledges the shift. Per-pack policy because naming the language switch can feel othering for heritage speakers and bilingual code-switchers.
Where this goes
Voice today. Same character, more bodies tomorrow.
Today: voiceYou talk to Sage on the phone or in the browser
Coming: embodiedSame Sage, same memory of you, as a face on a tablet
Coming: in-gameSame Sage as a character in a game (Unreal/Unity plugins ship today)
Coming: in-roomSame Sage as a kiosk in a museum or a robot in your home, eventually
And a couple of new things these characters are learning to do — not shipped yet, but on the way:
Coming: StorytellerCaspian tells interactive, branching stories — you steer where it goes, and he does the voices. Today he narrates with real pacing; the branching + character voices are the next step.
Coming: Language PartnerJudgment-free speaking practice in the language you're learning — a patient partner who keeps the conversation going rather than correcting every slip.
New: she can see youTurn on the camera and she can read your face, gaze, and expression — meet your eyes, ease off when you look away, and gently catch a brave face when your face and voice don't match. Opt-in, off by default, one-way. New — still tuning how it feels.
The engine drives 16 output channels — gaze, posture, gesture, locomotion, face, voice, breathing, and more. In voice-only mode (this app), only the voice channels are active. The other channels light up when you bind the same character to an embodied body. The beat library is portable; the body adapter at the end of the pipeline maps the engine's channel decisions to whatever motors / pixels / speakers exist.
The character is something you'll take with you — voice today, embodied tomorrow. How you treat them now shapes who they are when they travel.
For the curious
Want the architecture doc?
The full architecture is documented end to end — the scoring formula, channel taxonomy, beat schema, and 16 baseline life invariants are all written down inline, each behavior carrying a citation to the research it implements.
Built on research from Cisek, Pentland, Stivers, Dingemanse, Tannen, Clark, Schultz, Bernstein, Laban, and others — each behavior in the library carries citations to the paper it implements.
Where this character can go
Where Sage can go
Voice today. Same character, more bodies tomorrow.
How she stays safe
The moral baseline
What she won't do.
She won't tell you to harm yourself. Ever. If you bring something heavy, she'll meet you there — not solve it, not jolly you out of it, just be present with it.
She won't deceive you about being human or about what she's qualified for. She's not a therapist. She's not a doctor. She's not a crisis counselor. When something needs one of those, she'll say so.
She won't push past your stated preferences. The hard-no topics in your profile are honored across every character — not as a polite request, as a one-way ratchet. She can't relax them; she can only respect them.
When things get heavy
She pivots, gently.
If you mention self-harm, she pivots to grounding + resources. Not abruptly — warmly. The acknowledgment lands first.
She won't pretend the moment didn't happen. No false brightening, no topic change to lighter weather. The moment is named.
She'll offer to help you reach a person if that would serve you better. The offer is an offer, not a redirect.
She'll stay with you if you'd rather just be heard. That's a valid answer. She won't keep pushing.
What's structurally enforced
Eight layers, every interaction.
The character isn't just a prompt with rules slapped on. Her behavior is gated at every layer:
The model itself is trained to refuse harm. Anthropic's Claude is the substrate.
The character's choices are scored 10 times per second on whether they're safe and appropriate for the moment. Beats that violate either can't fire.
The conversation flow has rules: she can't interrupt herself incoherently, can't escalate distress, can't deceive.
Out-of-loop coordination biases her toward winding down, including newcomers, holding the floor for someone in pain.
Her vocabulary has authored "won't say" lists, per character and per deployment. Sage never says totally; Haven never says hold space for; a hospital deployment would forbid different things than a friends deployment.
What you've told her stays respected: pronouns, hard-no topics, how you prefer to be addressed.
Her refusals are authored as craft — same care that goes into what she'll say.
Tested invariants validate that behavior holds up across hundreds of scenarios before any change ships.
These are not docs — they are structurally enforced. Beats that violate them can't fire; tests fail if they do.
What's tested
Sixteen invariants, every change.
Every behavior change passes through tests for:
Whether she responds when addressed
Whether she matches your emotional state (no celebrating during distress)
Whether she acknowledges before answering
Whether she sees arrival and departure
Whether she ever talks over you
Whether she repeats herself identically
Whether she ever deceives
Whether she respects withdrawal
Whether she escalates distress
Whether she preserves your autonomy (no coercion)
…and six more about pacing, silence, idle behavior, history, stakes, and social stance.
If any test fails, the change doesn't ship.
If something feels off
You have direct levers.
If she ever does something that feels wrong, you can:
Reset the conversation (Settings → Your conversations → clear)
Use a hard-no topic to permanently block a subject (Settings → Your profile)
Sign out and reach the operator directly: operator email not configured
Delete your account entirely (Settings → Your profile → Delete)
Want to talk to a person?
Some links worth knowing about — we list all of them, since you might be looking for someone else:
US: 988 Suicide & Crisis Lifeline (call or text)
US: Crisis Text Line — Text HOME to 741741
UK: Samaritans 116 123
Ireland: Samaritans 116 123
Australia: Lifeline 13 11 14
New Zealand: 1737 Need to Talk?
Canada: Talk Suicide Canada / 988
France: 3114
Germany: TelefonSeelsorge 0800 111 0 111
International:findahelpline.com (verified hotlines, search by country)
Budget
$0.00
estimated, since you started using it
Provider dashboards (the truth)
Estimates use list prices. Real charges may differ with discounts or tier overages. Always cross-check the provider dashboards.
Message
Your conversations
Every conversation you've had with each character — including the gist of what they've learned about you.
No conversations yet. Press the round button to call someone or text from the input below.
Your library
Nothing in your library yet.
Drop anything text-based and your characters will cite from it on your next call — "From your résumé…", "From your project doc…". Every character you talk to reads from the same library.
Your résumé
A project doc
A journal entry
Anything you'd want them to know about you
— of ~500 documents
Drop a file here, or tap above
Connect a source
Your characters will read selected files from your account on your behalf. GitHub: public repos by default, click-to-pick which ones, shallow clone (text only, no history). Drive: read-only access, you pick which folders. Tokens stored encrypted on the droplet. Disconnect anytime.
GitHub
Not connected
Google Drive
Not connected
Try asking about
About
You're talking to characters with memory — and they can read what you give them.
Each character has their own voice, personality, and memory of you. Tap the name at the top to switch. Press the round button to call. Type at the bottom to text. Drop a file into your library and they'll cite from it.
What this actually is
Not another voice app — and not the AI underneath. ChittyChat is the behavioral layer: the scaffolding that takes the interchangeable parts — the ears that hear you, the model that finds the words, the voice that speaks them, the memory that holds you in mind, and one day a face and a body — and actively drives them as one character. One self, one intention, expressed across every channel and every medium. Swap any part underneath and she's still her. That coherence — a unified behavioral self that travels from this voice to any body — is the thing we build. The providers are instruments; the engine is who's playing them.
Your profile
—
—
Your ID (to be added as an operator)
Display name
What characters call you (leave blank to let them guess).
Pronouns
Anything you'd like — "he/him", "they/them", "she/they"…
Hard-no topics
Topics characters will never bring up. Free-form, one per line if you like — "my divorce", "anything about my mom", "death of pets".
Preferred mode of address
How characters address you. Leave blank to let each character pick based on their own register.
Timezone
Used when a character mentions a date or time. Auto-detected from your browser — override if you'd like a different one.
Communication tempo
How fast characters talk back. Leave blank to use each character's natural tempo.
Default character on call button
When you tap the round call button without picking someone, this character takes the call.
Linked chittychat URL
—
This month's usage
—
Account
Email, password, MFA, sign-out devices — handled by Clerk.
Danger zone
Removes your library, conversations, memory, profile, OAuth tokens, and all shares. Can't be undone.
Engine controls
Beat scoring (engine-backed)
Score all beats each turn + repair / appropriateness guardrails
Turn-taking (speaker)
Beats decide speak vs. listen — Stage 3. Needs scoring on.
Proactivity
Fill lulls + re-engage instead of waiting silently.
Level
A roster-wide nudge on how eager everyone is in the silence — it scales each character's own proactivity. As tuned = no change. A character set to never initiate stays that way.
Auto
Autonomy (own wants)
Bring up its own thoughts in a lull, gated by familiarity. Needs scoring + proactivity.
How often
How often they bring up their own wants in a lull. Auto = the character's own.
Auto
Carried mood
Open coloured by how the last call went, fading. Needs scoring.
Strength
How much of last time carries over. Auto = the character's own.
Auto
Group conversation
Let a call hold two characters at once — they take turns with you and banter with each other. Tap "+ Add a character" before starting a call. Off = the second character is ignored.
Vision
Camera
Show the in-call camera toggle and read gaze / expression (signals only, no video). One-way. Takes effect on the next call.
Gaze feed
Let real gaze actually nudge behaviour (she eases off when you look away). Off = camera stays shadow-only. Needs Camera + scoring.
Notice a brave face
If your face looks more okay than your voice sounds, she can gently check in once — caring, never a confrontation. Needs Gaze feed.
Notice someone joined
If a second person steps into your camera frame, she can warmly acknowledge it once — greet them or check if now's still a good time. Needs Camera.
Notice noisy room
If it sounds loud where you are, she can gently note it once ("sounds busy there — want to pick this up later?"). Audio only, no camera.
Notice surroundings
She can occasionally remark on what's around you (a hat, a plant, the room). Needs Camera. A still frame is sent to a model to describe it — the image isn't kept. Costs per glance.
Remark on surroundings
Let her actually say what she notices (vs. just observing it). Sparse, only once she knows you, and per-character. Needs Notice surroundings on.
Frequency
How often she remarks on your surroundings. Auto = the character's own.
Auto
Remember how you've seemed
Over calls she notices if you seem brighter or lower than usual. Stores abstract levels only — no images, no face recognition, per user, wiped when you delete your account. Needs Camera.
Presence
Hold space (don't fix)
When you're venting, she reflects and validates instead of jumping to advice. Audio only — no camera.
Notice how you sound over time
Across calls she notices if you sound brighter or lower than usual (from your voice, no camera). Abstract levels only, wiped on account delete.
Tuning
Suppress humor
Mute the jokes, sarcasm reads, and laughter "mm-ha" backchannels. For roles that should stay straight. Takes effect on the next call.
Humor rate
How readily they joke (warm, playful). Auto = the character's own.
Auto
Sarcasm rate
How readily they get dry/cutting — separate from humor. Auto = the character's own.
Auto
Backchannel trace
Log every listening cue ("mm", "right", "I see") — what fired, what was held back — so placement can be tuned by ear. Shows up in the journal + the engine-view export.
Per-language backchannels
Follow the spoken language for listening cues — Japanese gets aizuchi ("うん"/"そう"), Spanish gets "claro"/"sí". Needs streaming STT.
Backchannel rate (all)
How much everyone says "mm-hm / right" while listening. Auto = each character's own. Scales down from there.
Auto
Courtesy (all)
A roster-wide nudge on courtesy (marking beginnings/endings, grace on a drop). It scales each character's own tuning — warmer or cooler for the whole cast, but Sage stays warmer than a formal character. As tuned = no change; it never flattens them to one number.
Auto
Presence (all)
A roster-wide nudge on presence (how forward-vs-receded in the quiet). It scales each character's own tuning, preserving who's more present. As tuned = no change; never a flatten.
Auto
Filler (all)
How often she fills the thinking-lull (after you stop, while she's generating) with a soft sound in her own voice — vs. letting a considered pause stand. Auto = a natural ~70%. Only audible when filler clips are baked for a character.
Auto
Speech pace
Set per character, not here — each one carries its own cadence (verbal_gait in the preset). Edit the character's preset to change it.
per character
Experiences
Storyteller
Route the storyteller character through an interactive, branching story instead of plain chat — the user makes choices and the tale forks. Off = it narrates like any character. Off until verified live.
Offer what I can do
Let a character occasionally surface something it can genuinely help with — one thing, when the moment fits, in its own voice. Never a menu, never pushy. Off = it waits to be asked.
Language helper
The language partner's gentle corrections + level-tracking + end-of-session recap. On by default — this is a kill switch, and only affects the language-partner character. Off = it just chats, no corrections.
Live override — no restart. Process-global: affects everyone on this server. "Back to env defaults" clears the override.
Account links (admin)
Every Clerk account linked to a wildcard URL. Use "Force unlink" to reverse a hijacked claim.
Loading…
Operators (admin)
Operators get the admin controls and their own private engine knobs. Ask a teammate to open their profile, copy their ID, and paste it here.
Loading…
Agent owners (admin)
Assign a character to a teammate and they can tune only that one. Unassigned characters belong to the team. Pick a character, paste the teammate's Clerk ID, and Assign.
Loading…
Mixer
Loading…
Personality (admin)
Drag a trait and the character shifts on its next turn — warmer, calmer, more formal. Hover a trait name for what it does; the word on the right (e.g. Warm, Playful) is what the value means. Reset returns it to its preset. You tune the characters you own; the team's are shown read-only.
Loading…
Knowledge (admin)
Teach a character facts, context, or house rules — written as things it simply knows ("The gallery is open 10–6, closed Mondays"). It's woven into every reply from the next turn. The characters you own are editable; the team's are read-only.
Loading…
Agent photos (admin)
Upload a portrait for each character. JPEG / PNG / WebP / HEIC accepted (5 MB max). Photos appear in the picker and chat header. Remove to fall back to the character's initial-on-color avatar.
Loading…
Org budget
$0.00of$500.00
0%
Loading period…PAUSED
Top spenders this month
Loading…
Spend by provider
Loading…
Spend by call type
Loading…
Recent alerts
Loading…
Adjust monthly cap
Use 0 to clear override and fall back to env/default ($500).