Overlay an AI-driven fake chat on top of your live recordings. The chat reacts to what you say (via your mic), and you steer it in real time — dial it from savage to adoring, fire off hype/roast/absurd bursts, or push an operator override that the bots must obey on their next lines.
Rebuilt as a Next.js webapp: browser-native speech-to-text, Claude via the Vercel AI Gateway, and a realtime overlay you can drop into OBS.
The control panel is the brain. It runs while you stream, so it owns the timing:
Control panel (browser) Vercel (stateless) Overlay (OBS / tab)
├─ Web Speech API STT ──────┐
├─ sentiment + intensity │ POST /api/generate
├─ ambient chatter loop ────┼──────────────► AI Gateway → Claude Haiku 4.5 / Sonnet 5
└─ broadcasts messages ──────┘ │
▼
realtime channel ◄──── returns one chat line
(Supabase / server relay / BroadcastChannel) ──► renders chat
- Video stage: the panel composites your camera or screen share with the chat
overlaid in a corner (like a real Twitch layout) — no OBS needed to see the result.
Fullscreen it or open the chromeless
/stageroute to screen-record a clean 16:9 output. - STT: Web Speech API — interim transcripts as you talk, no upload (~0.3s). Chrome/Edge.
- LLM: routed through the Vercel AI Gateway as
anthropic/claude-haiku-4.5(fast, default) oranthropic/claude-sonnet-5(richer). Swap the model live in the UI. - Realtime: Supabase Realtime broadcast when configured (cross-device, OBS), else BroadcastChannel (same-browser, zero-config — good for dev and the in-panel preview).
npm install
cp .env.example .env.local # then fill in AI_GATEWAY_API_KEY (see below)
npm run devOpen http://localhost:3000 for the control panel. Flip LIVE, allow the mic,
and talk — or use the Say something box / Quick fire buttons to test without
a mic. The ⚡ Emotes button and manual sends work with no API key.
Bots need the Vercel AI Gateway. Create a key at
https://vercel.com/[team]/~/ai-gateway/api-keys and set it in .env.local:
AI_GATEWAY_API_KEY=your_key_here(On a Vercel deployment this is provided automatically via OIDC — no key needed.)
OBS's Browser Source is its own embedded Chromium — a separate browser from the
tab running the control panel — so a same-browser transport (BroadcastChannel)
can't reach it. The app ships with a same-origin server relay (SSE via
/api/realtime) that bridges any browser on the machine with zero setup:
- Run the app (
npm run dev, ornpm run build && npm run start). - In the control panel, copy the Output → overlay URL (
/overlay?room=live). - In OBS: Sources → + → Browser, paste the URL, set Width 1920 / Height 1080. Leave "Shutdown source when not visible" off so it stays connected.
- Position it over your scene. The background is transparent — only the chat shows.
- Flip the panel LIVE (or use Quick fire / Say something) and lines appear in OBS.
The panel's realtime indicator will read server relay (OBS-ready). Because relay state lives in the server process, this covers a local rig (panel + OBS on one machine, or same LAN). For a separate device or a deployed (multi-instance) setup, add Supabase and the app upgrades automatically:
NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_keyNo database tables are required — we use Realtime broadcast. openChannel prefers
Supabase when these are set, then the server relay, then BroadcastChannel.
npm i -g vercel && vercel # preview
vercel --prod # productionSet AI_GATEWAY_API_KEY (or rely on OIDC) and the two NEXT_PUBLIC_SUPABASE_*
vars in the Vercel project. See vercel:env / vercel deploy for the flow.
| Control | What it does |
|---|---|
| Sentiment dial | Re-weights bot personas from Savage → Neutral → Adoring |
| Intensity | How chatty/reactive the room is (reply chance + ambient cadence) |
| Quick fire | Instant Hype / Roast / Confused / Absurd bursts, or raw emote spam |
| Operator override | A directive the bots must follow literally on their next lines |
| Model | Haiku 4.5 (fast) ↔ Sonnet 5 (rich), live-switchable |
| Bots / Creativity / Stream context | Room size, temperature, what you're doing |
| Video stage | Camera / screen source, chat corner, fullscreen — the composited output |
- Presets (save/load persona + sentiment configs) — port from the old SQLite model
- Persist chat history to Supabase Postgres (currently ephemeral broadcast)
- Streaming token-by-token rendering for a "typing" feel
- Per-bot model assignment; more persona packs