Skip to content

Voice assistant: hands-free barge-in (WI-174 v2) - #685

Merged
thedancingdeveloper merged 1 commit into
mainfrom
feat/voice-handsfree-v2
Sep 10, 2026
Merged

thedancingdeveloper merged 1 commit into
mainfrom
feat/voice-handsfree-v2

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Contributor

Supersedes #682 (auto-closed when its stacked base feat/voice-handsfree merged as #680). Now a single commit on main.

Opt-in barge-in for hands-free mode (interrupt_response=1): the speaker can talk over a playing reply — the device stops speaking and listens the moment they start.

  • voiceTurn.tsspeechDetected(): halts the reply + re-opens the mic, gated on interrupt_response and a reply actually playing.
  • voiceVad.ts (new) — a pure leaky-accumulator OnsetDetector over frame RMS (~500 ms sustained onset fires once; a click/AEC residual doesn't), unit-tested; a thin echo-cancelled getUserMedia → AnalyserNode capture shell a WASM Silero VAD can replace behind the same seam.
  • Assistant.tsx — runs the capture only during speaking, torn down when playback ends.

Off by default (imperfect WebView AEC). Full web unit suite green (931); a real-browser Playwright test proves the halt + reopen. Docs: ENGINE.md §6, USER_GUIDE §2.5.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BojRRh8yXBBqwemk6WkqVo

Lets the speaker talk over a playing reply: with interrupt_response on, the
device stops speaking and listens the moment you start.

- voiceTurn: `speechDetected()` — halts the reply and re-opens the mic, gated
  on interrupt_response and an actually-playing reply, so a stray onset outside
  playback cannot disturb the loop; the halted reply's own speechFinished is
  then ignored. Unit tests for off (default), on, and outside-playback.
- voiceVad: a pure `OnsetDetector` (leaky accumulator over frame RMS — a
  sustained ~500 ms onset fires once, a click or the AEC residual does not) +
  `frameRms`, unit-tested off frame energies; a thin `startBargeInDetection`
  Web Audio shell (echo-cancelled getUserMedia → AnalyserNode, 50 ms frames)
  that a WASM Silero VAD can replace behind the same seam later.
- Assistant.tsx: runs the echo-cancelled capture only during `speaking` (a
  createEffect on voiceState), torn down the moment playback ends — the second
  mic is never held longer than the reply it listens over. Off by default
  (imperfect WebView AEC can false-trigger); config vogt.assistant.voice.
  {interrupt_response,vad_threshold,vad_onset_ms}.

Tests: full web unit suite green (931); a real-browser Playwright round trip
proves the halt + reopen. Docs: ENGINE.md §6 + USER_GUIDE §2.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BojRRh8yXBBqwemk6WkqVo
@thedancingdeveloper
thedancingdeveloper merged commit 5cd29c8 into main Sep 10, 2026
15 checks passed
@thedancingdeveloper
thedancingdeveloper deleted the feat/voice-handsfree-v2 branch September 10, 2026 03:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant