A password-gated voice agent built on ElevenLabs Conversational AI. It answers only from my resume, project history and a red-teamed knowledge base, in my cloned voice, for up to ten minutes.
For the past few years, most people have used AI through a chat box. That isn't how people naturally communicate, and voice removes a lot of the friction of typing at a computer.
So I built one: a live agent visitors can talk to, grounded in a knowledge base I control, that tells you when it doesn't know something.
Answer from the files, or say so.
Every claim the agent makes has to trace back to an uploaded document. If retrieval finds nothing, it says so. A made-up claim about my career is the one failure this build is designed to prevent.
A session flows left to right. Solid stages run in my own Next.js code. Dashed stages hand off entirely to ElevenLabs' infrastructure.
The WebSocket handshake looked the same whether the call worked or not: DevTools showed a clean 101 Switching Protocols and a conversation ID either way. The bug wasn't in the network. Next.js's dev-mode Fast Refresh was remounting the component that owned the connection mid-handshake, leaving the connection attached to a component that no longer existed. A production build, which has no Fast Refresh, connected on the first try.
The agent won't answer from general knowledge. If retrieval returns nothing, it says so. Before launch I red-teamed it against a fixed set of questions designed to draw out a confident, made-up answer.
Each password carries a ten-minute budget, tracked on the server and resumable across sessions. It syncs with sendBeaconwhen a tab closes, because a normal fetch isn't guaranteed to finish while a page unloads. A silence watchdog in the browser ends idle calls, since ElevenLabs' dashboard has no per-session setting for that.
I rate-limited myself while debugging. The guard that stops password guessing also counted every retry, so I restarted the dev server to clear the in-memory counter.
There's another public Siri Rama, a dancer with a PhD in Fine Arts. The knowledge base tells the agent to ignore anything it already knows about the name, so it never answers as the wrong person.
Signed URLs expire quickly, so they're created when a visitor taps “begin” instead of at page load or password entry.
Highlighted: a slow heartbeat that arrives after a newer one can't add time back. The budget only goes down.