Documentation
¶
Overview ¶
Package realtime implements a transparent, provider-agnostic websocket reverse proxy for OpenAI-compatible realtime (speech-to-speech) sessions. The provider event schema is the wire format, so frames are relayed verbatim; the gateway's job is credential injection, routing, and observation.
Index ¶
Constants ¶
const (
DefaultCallTTL = 6 * time.Hour
)
DefaultCallTTL bounds how long a WebRTC call stays routable (registry entries and sideband observers): a realtime call outliving it has long ended upstream. maxCalls bounds memory if entries are registered faster than they expire. Both are far above realistic session counts and durations.
const MaxFrameBytes = 16 << 20 // 16 MiB
MaxFrameBytes caps a single realtime message. OpenAI streams base64-encoded audio inside JSON text frames that routinely exceed coder/websocket's 32 KiB default read limit, so the limit is raised well above the largest expected event. Frames larger than this fail the session rather than truncating audio.
Variables ¶
This section is empty.
Functions ¶
func Observe ¶
Observe dials the target websocket and consumes frames until the upstream closes or ctx is canceled, invoking tap on each frame. It backs usage tracking for WebRTC calls: their events flow over the peer connection's data channel and never pass through the gateway, so the gateway attaches to the call's sideband channel and watches for usage events itself.
The relay's heartbeat cadence applies here too: a silently dead provider connection surfaces as a ping timeout instead of leaving the observer blocked in Read until the call TTL expires.
A dial failure is returned as *DialError; a clean close returns nil.
func Proxy ¶
Proxy upgrades the client request to a websocket, dials the upstream target, and relays frames bidirectionally until either side closes. onServerFrame, if non-nil, observes each upstream->client frame for usage tracking; it must be fast and must not block.
The upstream is dialed first: if it fails, the client is not yet upgraded, so a *DialError is returned and the caller may write an HTTP error. Once the client is upgraded the connection is hijacked; Proxy then returns nil on a clean close or the terminal transport error (never a *DialError) for the caller to log.
Types ¶
type CallRegistry ¶
type CallRegistry struct {
// contains filtered or unexported fields
}
CallRegistry is an in-memory call_id -> route map. Like the rate limit counters, it is per-instance state: after a restart (or on another replica) clients fall back to passing model and provider explicitly.
func NewCallRegistry ¶
func NewCallRegistry() *CallRegistry
NewCallRegistry returns an empty registry with production defaults.
func (*CallRegistry) Lookup ¶
func (r *CallRegistry) Lookup(callID string) (CallRoute, bool)
Lookup returns the route registered for a call id, if it is still live.
func (*CallRegistry) Register ¶
func (r *CallRegistry) Register(callID string, route CallRoute)
Register remembers the route for a call id. Empty ids are ignored.
type CallRoute ¶
CallRoute remembers which model and provider a WebRTC call was created with, so a later sideband attach (GET /v1/realtime?call_id=...) can route to the same upstream without the client restating them.