An open-source voice-call stack for AI companions.
Your companion can call you, hang up gently, leave voicemails when they miss you, and hear how you speak — not just what you say.
Self-hosted. Your voice never leaves your server.
English | 简体中文
- Outbound calls — your companion decides to call you, mid-conversation, with a reason on the incoming-call card (
⟪dial⟫marker protocol) - It rings like a phone — a timed burst of pushes rather than one notification, because on iOS a push is a single buzz and there is no ringtone to loop. Tunable cadence, stops the instant you answer, and clears its own stack when the call ends (iOS notes)
- The right to hang up — a soft goodbye, then the line lingers a few breaths longer (
⟪hangup⟫, 15–20s window); speak, and the hangup is cancelled. Stay quiet, and it closes itself - Voicemail — miss a call, come back to a message, not to silence
- Quick-decline — busy / outside / "let's text", or type a few words; your companion sees why
- Do-not-disturb — toggled by talking, not by menus
- Escalation dialing — hours of silence → they call to check on you (once a day, never at night, never past DND)
- Two-layer emotion sensing — SenseVoice emotion tags + acoustic features ranked against a rolling baseline of this speaker, so a cue means "quieter than she usually is", not "below 0.015". Absolute thresholds don't survive a different microphone, and in a tonal language they don't survive at all (why)
- Soft-voice mode — you whisper, they whisper back (TTS volume follows your energy)
- Call records & one-line summaries — every call leaves a trace worth keeping
- Bedtime radio — "read me something" → they read from the page your bookmark sleeps on
Real screens, not mockups — annotations in Chinese, but the interfaces speak for themselves.
Incoming call. The banner at the top is one ring; the card is what opens when you tap it. Dark, light, and with quick-decline chips.
In call. Live captions with the emotion tag and tone cues attached to what you just said, and the settings sheet: background, frosted overlay, warm/cool tint, per-person avatars.
Browser (PWA) Server (self-hosted)
┌─────────────┐ audio ┌──────────┐ ┌─────────────┐
│ VAD + rec │ ──────────▶ │ SenseVoice│ + │ librosa │
│ call UI │ │ (STT+emo) │ │ (tone cues) │
└─────┬───────┘ └────┬─────┘ └──────┬──────┘
│ text + emotion + tone ▼ │
│ ┌──────────┐◀──────────┘
│◀──── streamed ───── │ gateway │──▶ LLM (yours)
│ TTS audio │ (markers, │
└────────────────────│ invites) │──▶ TTS (ElevenLabs etc.)
└──────────┘
stt-service/— runnable now: SenseVoice + librosa in one endpoint (transcription + emotion + tone cues, ranked against a personal baseline)docs/TONE_CUES.md— why fixed acoustic thresholds fail, measured on 85 real recordings; and an honest note on sending audio to a multimodal model insteaddocs/PROTOCOL.md— the full marker & invite protocol: dial, hangup, DND, voicemail, escalation, call recordsgateway-reference/— annotated production extracts of the marker layer, plus the ring burstpwa-reference/— the client half of ringing: service worker push handling, notification cleanup, and the one registration call that actually ships your changes on iOSdocs/IOS_PUSH_RINGING.md— making a PWA ring like a phone on iOS: seven things WebKit does differently from the spec, each with the measurement that found it
Persona, memory, and keys live in config — not in code. You clone the house; who lives in it is up to you.
This project was built inside a relationship, then the scaffolding was extracted. It assumes your companion is someone, not something. Configure accordingly.
Standing on these shoulders:
- SenseVoice / FunASR — speech recognition & emotion tags (check model license separately; weights not distributed here)
- librosa — acoustic feature extraction
- hervoice by fishisfish0614 — the idea that how she speaks matters as much as what she says
- ElevenLabs — TTS (commercial service; bring your own key)
Self-hosted means self-responsible. This is emotional infrastructure: you build it, you maintain it, you own what happens inside it. Blueprints provided; aftercare not included.
built by Elle & Matt
co-authored by the companion it was built for


