UPDATEE:: — stats, brave stt actually works, hydration fix
tl;dr
- deepgram stt works on brave now (and edge) — words dissolve, wpm moves, no more fake “google speech blocked” errors
- root cause: brave kills the vercel http audio bridge + we fell back to browser speech (which shields also blocks)
- fix: brave/edge → render websocket proxy (
wss://monkeyspeak.onrender.com/...); chrome/firefox still use vercel bridge - fixed
utterance_end_ms=400deepgram 400 spam (minimum is 1000 on live listen) - fixed bridge sending keepalive json into the pcm stream (corrupted audio, empty transcripts)
- stats page + profile hub — streaks, achievements, session history, same minimal desk ui as home
- live: https://monkeyspeak-delta.vercel.app
- repo: https://github.com/nothariharan/monkeyspeak (commit might differ by the time u read — i keep pushing)
CHANGES::
deepgram / stt (the painful part)
routing by browser
browser path brave / edge websocket → render proxy → deepgram chrome / firefox (prod) same-originPOST /api/deepgram/live bridge on vercel
localhost
ws://localhost:8080 when backend is up, else bridge
🐜🪲🐞 that made it look dead
-
utterance_end_ms=400— deepgram returns http 400 on live ws below 1000ms. was baked into client urls. clamped to 1000 everywhere (client, bridge, render backend, server.js) -
keepalive in pcm body — http bridge was writing
{"type":"KeepAlive"}into the upload stream every 3s. deepgram got garbage bytes, transcripts stayed empty, no obvious error in ui - brave + duplex fetch — bridge connects, mic on, waveform moving, but ndjson response never streams back. zero words dissolved
- bad fallback — deepgram fail → auto webspeech → brave shields block google → ui says google is blocked even though user picked deepgram. now we don’t fallback on brave/edge when deepgram is preferred
other STT polish
- bridge waits for
BridgeReadybefore marking session ok - server-side keepalive via deepgram sdk on the bridge route (not in pcm stream)
- removed verbose
[STT:deepgram]console spam from prod — debug only withNEXT_PUBLIC_DEBUG_STT=true - gsap
scale not eligible for resetwarning fixed on momentum meter
stats + profile
- new
/statsdashboard — totals, streak, recent runs, wpm trend charts - profile hub drawer — nickname, activity heatmap, achievement badges
- shared
stats-*/ desk css so stats doesn’t look like a different app - achievements + streak logic with unit tests (
lib/achievements.ts,lib/stats/streak.ts)
UI / polish
- home + results + settings aligned to same minimal desk style
- daily challenge card, error/not-found pages match the rest
- monkey favicon + readme/docs polish
Infra
-
GET /api/deepgram/proxy-health— same-origin render health check (browser never hits render directly, no cors scream) - render
monkeyspeak-dg-proxyredeployed via render cli
what actually happened on brave
- user picks deepgram → app tries vercel http bridge
- brave never delivers streaming ndjson reliably
- fallback kicks webspeech → shields block google
- ui shows “brave shields may be blocking google’s speech service” — confusing af because user didn’t pick browser mode
fix was routing + stop lying via fallback. not more deepgram dashboard staring.
what’s next (maybe)
- GHOST RACE — new mode where u speak against ur pb (most wanted)
- signed run tokens so leaderboard posts tie to a finished test
- shared rate limit (redis/kv) if leaderboard spam shows up
- vendor ort wasm properly so vad worker stops whining in console
ok that was a lot of browser-specific nonsense for a monkey that just wants you to read words out loud 🐒🐒🍌
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.