Voice agents in Go.

Real-time voice agents for the browser, phone, LiveKit and WhatsApp.

0:00 / 0:00
  1. Audio in
  2. VAD
  3. STT
  4. LLM
  5. TTS
  6. Audio out

Each stage runs on its own goroutine.

One static binary

The default build is cgo-free. Low, predictable memory, fast startup, and real concurrency for many simultaneous sessions.

Standard WebRTC, self-hosted

Plain Pion WebRTC: no hosted transport, no proprietary SDK, no cloud to sign up for. Ship the binary; the browser connects.

Turn-taking that works

Silero VAD and Smart Turn v3 run locally on ONNX, so the bot waits for a real end-of-turn instead of any pause, and the user can cut in.

Pluggable providers

Swap any STT, LLM or TTS behind a small interface. 50+ providers, plus single-model speech-to-speech.

Concurrent by design

Independent processors, each on its own goroutine. Interruptions are frames, so barge-in reaches every stage at once.

Telephony included

Inbound and outbound phone calls over Twilio, Telnyx, Plivo and Exotel, with DTMF and an idle watchdog.

A pipeline is a list of processors.

Each provider is one line. The browser connects directly to your binary.

main.go
stt := openai.NewSTT(openai.STTConfig{APIKey: key, SampleRate: opus.SampleRate})
llm := openai.NewLLM(openai.LLMConfig{APIKey: key})
tts := openai.NewTTS(openai.TTSConfig{APIKey: key})

t := rtc.NewTransport(conn, transport.DefaultParams())
agg := aggregators.New(frames.NewLLMContext("You are a helpful voice assistant."))

task := pipeline.NewTask(pipeline.New(
    t.Input(), stt, agg.User(), llm, tts, t.Output(), agg.Assistant(),
), pipeline.TaskParams{})
task.Run(ctx)