feat(realtime): gate realtime pipeline voice models behind voice recognition#10319
Merged
Conversation
Add the PipelineVoiceRecognition config block that gates a realtime pipeline behind speaker verification (identify against the voice registry, or verify against reference audios), with Normalize defaults and Validate enum/shape checks. Register the new fields in the config meta registry so the UI renders them with proper labels/components (required by the registry-coverage gate). Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Run speaker verification concurrently with transcription and join on a hard barrier before generateResponse, so unauthorized utterances never reach the LLM, tools, or TTS. Supports identify (registry) and verify (reference) modes with multiple authorized speakers, per-utterance or first-utterance checking, and drop-with-event or silent-drop on reject. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Only launch the verification goroutine on the transcription path and drain it before the temp WAV is removed on the transcription-error return, so an in-flight backend read never races the deferred cleanup. Drop the write-only voiceMatched field; log the matched speaker instead. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
A present voice_recognition block with no model previously disabled the gate silently, authorizing every speaker. Treat block presence as the intent signal and reject an empty model in Validate, so the session is refused instead of running unprotected. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
Drive the real commitUtterance path (gate goroutine, hard join before the LLM, reject event, when:first session trust) with the existing transport/model doubles: authorized speakers reach a full response, unauthorized ones are dropped before the LLM with a speaker_not_authorized event, backend errors fail closed, drop_silent stays quiet, and when:first trusts the session after one match. Signed-off-by: Ettore Di Giacinto <mudler@localai.io> Assisted-by: Claude:opus-4.8 [Claude Code]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an optional speaker-verification gate to realtime pipeline voice models (VAD → STT → LLM → TTS). When a model's YAML declares a
pipeline.voice_recognitionblock, every committed utterance is verified against authorized speakers, and unauthorized utterances are dropped before they reach the LLM (no LLM call, no tool execution, no TTS). The realtime session stays open.This connects the existing realtime API (WebRTC + WebSocket) with the existing voice-recognition subsystem (
/v1/voice/*,VoiceRegistry, SpeechBrain/ONNX speaker-recognition backend). No new infrastructure.Configuration
/v1/voice/register;allow.names/allow.labelsfilter who counts (empty = any registered speaker).Design
voiceGatecomponent (realtime_voicegate.go) with a singleAuthorizeentry point and testability seams (embedFn/verifyFn+ theRegistryinterface), so all decision paths are unit-tested without a live backend.generateResponse. An unauthorized utterance can never reach the LLM/tools/TTS regardless of how fast STT finishes.voice_recognitionblock (e.g. missingmodel) refuses the session rather than running unprotected.when: firsttrusts the session after one successful match (guarded by a mutex);when: everyre-checks each utterance.Testing
cosineDistance, identify mode (allow by name/label/empty, threshold, unknown speaker, no-speech, embed-fail, identify-fail), verify mode (match/no-match/no-speech/embed-fail, anti-spoofing + its error path), thedecidepolicy matrix, andnewVoiceGatefail-fast.go vetclean,go test -raceclean on the realtime package,golangci-lint --new-from-merge-basereports 0 issues.Notes
identifymode uses the existing in-memoryVoiceRegistry(lost on restart); persistence is future work.Assisted-by: Claude:opus-4.8 [Claude Code]