feat(desktop): flag huddle Smart Turn gate after VAD silence - #6354
Open
YoraiLevi wants to merge 6 commits into
Open
feat(desktop): flag huddle Smart Turn gate after VAD silence#6354YoraiLevi wants to merge 6 commits into
YoraiLevi wants to merge 6 commits into
Conversation
Co-authored-by: Yorai Levi <yorai.email@gmail.com> Signed-off-by: Yorai Levi <yorai.email@gmail.com>
Co-authored-by: Yorai Levi <yorai.email@gmail.com> Signed-off-by: Yorai Levi <yorai.email@gmail.com>
Co-authored-by: Yorai Levi <yorai.email@gmail.com> Signed-off-by: Yorai Levi <yorai.email@gmail.com>
Add the pinned Smart Turn v3.1 CPU frontend, cache, and fail-open VAD integration behind the disabled-by-default feature flag. Co-authored-by: Yorai Levi <yorai.email@gmail.com> Signed-off-by: Yorai Levi <yorai.email@gmail.com>
Co-authored-by: Yorai Levi <yorai.email@gmail.com> Signed-off-by: Yorai Levi <yorai.email@gmail.com>
The file-size ratchet caps src-tauri Rust at 1000 lines. models.rs was 994 on main and 1137 after the flag-gated cache; the download lives in a sibling module so the STT/TTS manager stays under the ceiling. Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Yorai Levi <yorai.email@gmail.com> Signed-off-by: Yorai Levi <yorai.email@gmail.com>
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.
feat(desktop): flag huddle Smart Turn gate after VAD silence
Verdict: after the existing ~300 ms VAD silence, an optional local classifier can HOLD (keep listening) or SHIFT (today's Parakeet flush). Default is off. PTT, the wire, and
SILENCE_FLUSH_FRAMESare unchanged.Implements the flagged prototype in #6346. Closest existing issue: that RFC. No duplicate implementation PR.
Enable:
BUZZ_HUDDLE_SMART_TURN=1(strict== "1";0/true/yesstay off).Why
Hands-free huddles treat any ~300 ms pause as end of turn, so the agent wakes mid-sentence. Retuning the silence window already failed (450 ms sluggish, 150 ms split sentences). This PR asks a small local model "did they finish?" at the same silence point.
What changed
Flag off, missing weights, load error, or inference error →
decision=None→ today's flush.Component map
Grey is unchanged. Only the boxed gate is new.
flowchart TB subgraph unchanged [Unchanged] mic[AudioWorklet 48 kHz] resample[rubato 48k to 16k] vad[earshot VAD] stt[Parakeet sherpa-onnx] tx["text_tx Receiver String"] post[pipeline spawn_transcription_task] relay[kind:9 to relay] acp[buzz-acp] end gate{{Smart Turn v3.1 HOLD or SHIFT}} mic --> resample --> vad vad -->|19 silent frames ~300 ms| gate gate -->|HOLD flag on| vad gate -->|SHIFT or flag off| stt --> tx --> post --> relay --> acpflowchart LR subgraph desktop [desktop/src-tauri huddle] sttFile[stt.rs worker] modelsFile[models.rs + models_smart_turn.rs cache] pipeFile[pipeline.rs kind:9] end subgraph voice [crates/buzz-voice] smartTurn[smart_turn.rs pad/norm/log-mel + ort] end subgraph acp [crates/buzz-acp] harness[event handling unchanged] end modelsFile --> sttFile smartTurn --> sttFile sttFile --> pipeFile --> harnessRed-proof
These tests were inverted on purpose, watched fail, then restored.
Flush/ rightKeep, exit 101speech_buf.clear()256/ right768, exit 101max − 8changed tomax − 7Production Keep only zeros
silence_frames(stt.rson_silence_threshold). Production classify usesprobability > 0.5with no extra sigmoid (smart_turn.rs).0.5is HOLD;0.500_001is SHIFT.G4.1 vs Fizz's pinned-Python golden (
transformers==4.44.0, not the Rust port): max abs err 1.192e-7 at row-major index 11100 (mel 13, frame 700). Floor on this clip is -0.110, not silence's-1.5. G4.1 is a feature-extraction gate, not an accuracy gate.Latency (kill-arm 2: GO)
Measured on MacBook Air, Apple M5, 32 GB. Implementation SHA
b4a8fada. Pinned CPU graph SHA-256fb68d55c…c6594. Exact T4g PCM fixture. 3 untimed warm-ups, then 20classifycalls (pad/norm/log-mel + ONNX).19-frame VAD window is 304 ms. p50 / 304 ≈ 0.24. Added SHIFT delay is tens of ms, not hundreds.
Caveat: one fast ARM class. The flag stays default off, so a slower laptop is not the shipping path.
Do not read Pipecat's 10–65 ms as a Buzz number.
Packaging
*.f32 binaryin.gitattributes(under* text=auto eol=lf). The 256 KB golden has no NUL in the first 8 KB, sotext=autoclassified it as text. Today it round-trips (zero CRLF). A later fixture with0x0D 0x0Awould strip a byte and break G4.1.Smart Turn download/cache lives in
models_smart_turn.rssomodels.rsstays under the 1000-line ratchet (994 → 999). Flag, SHA pin, and fail-open are unchanged.Out of scope (intentional)
SILENCE_FLUSH_FRAMESHow to test
BUZZ_HUDDLE_SMART_TURN=1with weights cached under~/.buzz/models/smart-turn-v3.1/: a mid-sentence pause should HOLD; a finished turn should SHIFT into Parakeet.vad_flush_allowed).Commits
bcac097c9spike(voice): prove Smart Turn ONNX runtime6ffd155f4feat(desktop): add pure huddle turn gatea6a1e40e8feat(desktop): wire huddle turn gate stateb4a8fada3feat(huddle): classify semantic turn boundaries122233401chore: mark float fixtures as binary2897d060fchore(desktop): split Smart Turn cache out of models.rsHEAD:
2897d060fb31abd8b4be74fbbd4ab46d11368f4bonspike/huddle-smart-turn(base934f3325c).just cigreen on this tree:file-size-check(models.rs 994 → 999), workspace clippy/fmt, desktop pnpm check/test/build,cargo test --workspaceindesktop/src-tauri, web build,flutter test1544 passed.