jargo is a framework for real-time voice agents in Go: audio in over WebRTC, a streaming transcription → reasoning → speech pipeline with turn-taking and barge-in, and audio back out.
Warning
Early work in progress. Not ready for production. The public API is
unstable and changes in any release. Pin an exact version and read
CHANGELOG.md before upgrading.
Pipecat is great, and jargo is a port of it. The architecture and many design decisions are Pipecat's.
This port exists for one reason: I'd rather not run a voice agent on Python.
Python is the right tool when you need the AI/data-science ecosystem. A real-time voice server doesn't: the models run as services or as ONNX, and what's left is plumbing: audio framing, WebRTC, concurrency, and shipping a binary. For that, Go is a better fit: one static binary to deploy, low and predictable memory, fast startup, and real concurrency for many simultaneous sessions without a GIL. The heavy numerics stay where they belong (the ONNX Runtime, the remote services), so giving up Python costs little here. See the benchmarks for the honest performance picture.
- WebRTC, pure Go (Pion): audio in and out of the browser.
- Opus, pure Go encode + decode via pion/opus; C libopus optional with
-tags libopus. - Resampling, pure Go via go-resample; libsoxr optional with
-tags libsoxr. - Streaming voice pipeline: STT → LLM → TTS, with prompt caching.
- Speech-to-speech: single-model voice agents (OpenAI Realtime, Gemini Live, AWS Nova Sonic).
- Turn-taking & barge-in: Silero VAD + Smart Turn v3, local ONNX.
- Telephony (optional): inbound/outbound phone calls over Twilio Media Streams.
- User-idle watchdog: re-engage or hang up when the caller goes silent.
- RTVI data channel: works with existing RTVI clients.
- Pluggable services: swap any STT/LLM/TTS behind a small interface.
- Concurrent by design: independent processors; interruptions are frames.
Pick any per category; each is a small Config + constructor.
- STT: Deepgram, AssemblyAI, Gladia, Speechmatics, Soniox, Whisper (OpenAI/Groq/local), Azure, xAI, ElevenLabs, Cartesia, NVIDIA.
- LLM: Anthropic (direct + Bedrock), OpenAI (chat + Responses), Google Gemini (direct + Vertex), Groq, Together, Fireworks, DeepSeek, Cerebras, Perplexity, OpenRouter, xAI, Ollama, NVIDIA, Mistral, Nebius, SambaNova, Qwen, Azure OpenAI.
- TTS: ElevenLabs, Cartesia, Rime, LMNT, Kokoro, Piper, Pocket TTS, Deepgram, OpenAI, Azure, Hume, Fish, MiniMax, xAI, NVIDIA, Soniox.
- Speech-to-speech: OpenAI Realtime (direct + Azure), Gemini Live (direct + Vertex), AWS Nova Sonic, xAI Realtime.
- Memory: mem0.
go get github.com/gojargo/jargoA bot is an STT → LLM → TTS pipeline over a WebRTC transport. The heart of it:
stt := chat.NewSTT(chat.STTConfig{APIKey: key, SampleRate: opus.SampleRate})
llm := chat.NewLLM(chat.LLMConfig{APIKey: key})
tts := chat.NewTTS(chat.TTSConfig{APIKey: key})
t := rtc.NewTransport(conn, transport.DefaultParams())
agg := aggregators.New(frames.NewLLMContext("You are a helpful voice assistant."))
task := pipeline.NewWorker(pipeline.New(
t.Input(), stt, agg.User(), llm, tts, t.Output(), agg.Assistant(),
), pipeline.WorkerConfig{})
task.Run(ctx)examples/voice/openai is that pipeline as a complete
server (WebRTC signaling, VAD/turn-taking, barge-in).
Run it in Docker: build on the gojargo/jargo-build base and ship on the
distroless gojargo/jargo runtime (it bundles the ONNX Runtime), then:
docker run --rm -p 8080:8080 -e OPENAI_API_KEY=$OPENAI_API_KEY my-botSee Deploy with Docker for the Dockerfile and the Quickstart for the full setup.
Runnable bots live in examples/:
- echo: hear yourself back, no API keys.
- voicebot: the full voice agent (STT → LLM → TTS over WebRTC) with turn-taking, long-term memory, and tracing.
- voice/: one headless backend per provider, each wiring its STT/LLM/TTS
explicitly and exposing the WebRTC
/offerendpoint (no web UI). Run withgo run ./examples/voice/<provider>(e.g.deepgram,cartesia,openai) and drive it from a browser client, thenextjs-voicebotin jargo-client-react. - twiliobot: a phone agent over Twilio Media Streams, with the idle watchdog.
The fastest way to try them (locally or with Docker) is the Quickstart.
go run ./examples/echo # then open http://localhost:8080gojargo.github.io/jargo is the full
documentation. The same pages live in docs/ and read fine on GitHub.
Start with Architecture for the model, or Frames and Processors for the engine. Writing a processor covers extending it. The API reference is the Go reference.
The default build is cgo-free: CGO_ENABLED=0 go build ./... works with no C
toolchain. Two native runtimes are still used, but bound through
purego and loaded at run time, so they need
their shared library present at runtime and nothing at build time:
- ONNX Runtime: VAD + end-of-turn detection (
JARGO_ONNXRUNTIME_LIB). - RNNoise: optional input noise reduction (
JARGO_RNNOISE_LIB).
Opus and resampling are pure Go by default; the C libopus (-tags libopus) and
libsoxr (-tags libsoxr) are the only cgo in the tree, and both are optional. The
base images bundle all of them.
jargo is a Go port of Pipecat,
distributed under the same BSD 2-Clause License. The upstream copyright
(Copyright (c) 2024–2026, Daily) is preserved verbatim in LICENSE;
see NOTICE for details. jargo is an independent project, not
affiliated with or endorsed by Daily.