Multi-Provider Voice Routing
Production voice deployments rarely use a single provider for all sessions. Enterprise customers may require specific STT providers for compliance, regional latency differences may favor different TTS engines, and A/B testing demands side-by-side provider comparison. Multi-provider session routing selects the optimal voice provider combination per session based on tenant identity, geographic region, or feature flags — all without code changes. This guide covers implementing a routing layer on top of Beluga AI’s voice/session package.
Overview
Section titled “Overview”Rather than hardcoding a single STT/TTS provider, session routing evaluates context at session creation time and selects the appropriate providers. This supports multi-tenant deployments, A/B testing, and regional optimization without code changes.
Prerequisites
Section titled “Prerequisites”- Go 1.23 or later
- Multiple STT/TTS or S2S providers configured
- Routing criteria defined (tenant, region, feature flags)
Installation
Section titled “Installation”go get github.com/lookatitude/beluga-aiConfiguration
Section titled “Configuration”Define Routing Context
Section titled “Define Routing Context”Establish what drives provider selection for each session:
type RouteContext struct { SessionID string TenantID string Region string Features map[string]bool}Implement the Router
Section titled “Implement the Router”Select providers based on the routing context:
import ( "context"
"github.com/lookatitude/beluga-ai/voice/stt" "github.com/lookatitude/beluga-ai/voice/tts" s2spkg "github.com/lookatitude/beluga-ai/voice/s2s")
func SelectProviders(ctx context.Context, rc RouteContext) (stt.Provider, tts.Provider, s2spkg.Provider, error) { if rc.Features["s2s"] { s2sProvider, err := createS2SProvider(ctx, rc.TenantID, rc.Region) return nil, nil, s2sProvider, err } sttProvider, err := createSTTProvider(ctx, rc.TenantID, rc.Region) if err != nil { return nil, nil, nil, err } ttsProvider, err := createTTSProvider(ctx, rc.TenantID, rc.Region) return sttProvider, ttsProvider, nil, err}Use a configuration file or database lookup to map tenant/region to concrete provider types and configurations.
Create Sessions with Routed Providers
Section titled “Create Sessions with Routed Providers”import "github.com/lookatitude/beluga-ai/voice/session"
sttProvider, ttsProvider, s2sProvider, err := SelectProviders(ctx, routeCtx)if err != nil { return nil, err}if s2sProvider != nil { return session.NewVoiceSession(ctx, session.WithS2SProvider(s2sProvider), session.WithConfig(session.DefaultConfig()), )}return session.NewVoiceSession(ctx, session.WithSTTProvider(sttProvider), session.WithTTSProvider(ttsProvider), session.WithConfig(session.DefaultConfig()),)Add VAD and Turn Detection per Route
Section titled “Add VAD and Turn Detection per Route”Optionally attach VAD and turn detection providers selected by route:
import ( "github.com/lookatitude/beluga-ai/voice/vad" "github.com/lookatitude/beluga-ai/voice/turndetection")
vadProvider, err := vad.NewProvider(ctx, "webrtc", vad.DefaultConfig())if err != nil { return nil, err}td, err := turndetection.NewProvider(ctx, "heuristic", turndetection.DefaultConfig())if err != nil { return nil, err}sess, err := session.NewVoiceSession(ctx, session.WithSTTProvider(sttProvider), session.WithTTSProvider(ttsProvider), session.WithVADProvider(vadProvider), session.WithTurnDetector(td), session.WithConfig(session.DefaultConfig()),)Configuration Reference
Section titled “Configuration Reference”| Option | Description | Default |
|---|---|---|
| Routing key | Tenant, region, feature flags | Application-defined |
| Provider map | Tenant/region to STT/TTS/S2S config | Config file or DB |
| Fallback | Default provider when route is missing | Application-defined |
Troubleshooting
Section titled “Troubleshooting”Provider not found for tenant
Section titled “Provider not found for tenant”Fall back to a default provider. Log and emit metrics for missing mappings to identify configuration gaps.
Session creation fails after routing
Section titled “Session creation fails after routing”Validate provider configuration at startup or in a readiness check. Return clear errors with the routing context included for debugging.
Switching providers mid-session
Section titled “Switching providers mid-session”The session API does not support swapping providers during an active session. Provider failover requires creating a new session. Design routing logic to execute at session start only.
Advanced Topics
Section titled “Advanced Topics”Production Deployment
Section titled “Production Deployment”- Caching: Reuse provider instances per tenant/region to avoid creating new ones for every session
- Observability: Tag metrics and traces with route context (tenant, region) for debugging
- Testing: Unit-test the router with mock providers; integration-test one or two representative routes