agents-go
Transports

Transports

Get audio in and out — console, WebSocket, WebRTC (roomio), and bindings.

A transport provides the audio (and text) I/O an AgentSession binds to. The session is transport-oblivious — the same agent code runs over any of them, so picking one is a wiring decision, not an agent rewrite.

console

PCM over stdin/stdout. Zero setup — ideal for local dev and tests.

websocket

Raw WebSocket audio. The seam telephony (Twilio media streams) uses.

roomio (WebRTC)

LiveKit room audio + transcription. Production real-time voice.

console

Pipes signed-16-bit mono PCM. Everything runs inside console.Run, which hands your entrypoint a *console.Transport exposing tr.Input() / tr.Output().

import "github.com/webdeveloperben/agents-go/transport/console"

console.Run(ctx, console.RunOptions{
    Reader: os.Stdin, Writer: os.Stdout,
    Entrypoint: func(ctx context.Context, tr *console.Transport) error {
        session, _ := agents.NewSession(agents.Config{
            LLM:    "openai/gpt-4o", STT: "openai/gpt-4o-mini-transcribe", TTS: "openai/tts-1",
            Input:  agents.SessionInput{Audio: tr.Input()},
            Output: agents.SessionOutput{Audio: tr.Output()},
        })
        return session.Start(ctx, agents.StartOptions{Agent: agent})
    },
})

See Build a voice agent for the full console walkthrough.

websocket

The generic WebSocket transport carries audio over a socket — this is what the Twilio telephony path builds on. Each connection becomes one session; websocket.NewSessionHandoff bridges an accepted socket to a session function.

roomio (WebRTC)

roomio joins a LiveKit room and binds the room's audio I/O and transcription to a session. It carries the WebRTC/media stack, so it's a plugin and builds behind the livekit build tag (native Opus/SoXR):

import "github.com/webdeveloperben/agents-go/plugins/livekit/roomio"

// Binding form — the room connects and binds inside Start:
connectOpts := transport.RoomConnectOptions{URL: url, Token: token, ParticipantName: "agents-go"}
err := session.Start(ctx, agents.StartOptions{
    Agent:     agent,
    Transport: roomio.Bind(connectOpts, roomio.Options{}),
})

// Or the explicit form, when you need the RoomIO handle (e.g. rio.Room()):
rio := roomio.NewRoomIO(session, roomio.Options{})
err = rio.Start(ctx, connectOpts, agent)
go run -tags livekit ./examples/roomio

Where the URL, Token, and identity come from — and whether you mint the token yourself or the dispatcher hands it to you — is covered in Connecting to a room.

roomio is the only transport that needs a build tag, because it pulls the WebRTC/media stack. Console and WebSocket are pure Go and always available.

Bindings

A Binding lets a transport connect and hand its I/O to Start (rather than you wiring Input/Output by hand): Start calls Connect first, and closes the binding if start fails afterward. roomio.Bind above is the built-in binding; console and WebSocket keep their own Run/Handler entrypoints. See Reference → Transport for the interface.

Choosing

  • Local dev / tests → console.
  • Phone calls → websocket + the Twilio plugin.
  • Browser / app real-time voice → roomio.

On this page