Repository navigation
Hands-free: Stop steps down during a take (exit lock / cancel), noise-loop exit, stale-audio clear - #1353
Merged
Conversation
…-loop exit, stale-audio clear Stop was disabled during every take, and a hands-free loop is a take between turns, so the only exits were Clear (wipes the chat) or closing the sidebar. Stop Rec stays the send (loud rooms need it when silence auto-stop never fires). - send_state: Stop is enabled while recording. New CANCEL_REC_CLICKED / CancelRecordingEffect drops a take without the "Error" status. The deal contracts now allow Send+Stop only while recording. - panel: StopButtonListener steps down one level per click (locked take -> one-shot take still recording, status "Hands-free off" -> cancelled, recorder cleanup + WAV deleted). mousePressed stays busy-only so one click is one step. The speech-finished callback no longer greys Stop during a take. Silence progress reads "Hands-free..." while locked. - Two consecutive empty transcripts end hands-free (noise loop). - Stop before the send drain starts clears the pending WAV so a later typed Send cannot attach it. - Send/Stop tooltips explain Stop Rec = send, Stop = leave hands-free / cancel; labels unchanged (1x layout). - Stale send_handlers comments: Stop does not kill local Whisper. - docs/chat/audio-architecture.md: Stop-during-take and empty-take rows.
G4's stub silence auto-stop sent the take before a poll saw Stop Rec, so _send_event_or_urp fell back to a RECORD_CLICKED op and started a second take that never stopped. URP wait_idle (Stop off + Send on) hid it while Stop was greyed during takes; with Stop now enabled during a take it timed out.
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.
Problem
When hands-free (hold Record about 2 s) is on, the gap between turns is just another take. Stop was greyed out during every take (
send_state.pyRECORD_CLICKED hadstop_enabled=False, and the deal contracts required that). So the only ways out were Clear (which wipes the chat) or closing the sidebar. Headed tester report: Stop is greyed out while hands-free is listening between turns. Stop Rec can't be the exit, because it is the send, and in loud rooms where silence auto-stop never fires you need it to send.Change
Stop during a take now steps down one level per click:
CANCEL_REC_CLICKED/CancelRecordingEffectruns recorder cleanup and deletes the WAV. Nothing is sent, the status is "Recording cancelled" (not "Error"), and the button goes back to Record.send_statedeal contracts now allow Send and Stop to be enabled together only while recording. The why is in the comment abovenext_state.StopButtonListener.on_action_performed, viaSendButtonListener.stop_during_take. The GTKmousePressedhook still only acts while a send is busy, so one click is one step.Other fixes
EMPTY_TAKES_EXIT). A non-empty transcript resets the count.audio_wav_pathand the next typed Send transcribed or attached it. The skip branch now callsclear_pending_audio_wav().send_handlers._transcribe_audiosaid Stop kills local Whisper. It doesn't. Stop keeps the transcript for the Ask box, and only sidebar teardown kills the child.docs/chat/audio-architecture.mdgets rows for Stop during a take and for empty takes.Tests
test_send_state.py:test_fsm_verification.py: oracle and Hypothesis invariants updated to the relaxed contracts;CANCEL_REC_CLICKEDadded to the oracle.test_record_gesture.py: step-down decision, exiting the lock does not swallow the next Stop Rec, hands-free silence text,EMPTY_TAKES_EXIT.test_panel.py(TestHandsFreeRecord):test_mock_llm_sidebar_uno.py): with an in-process listener, Stop on a one-shot take now asserts cancelled (not recording, not busy, nothing sent).Local: the related pytest files pass (286), and ruff, basedpyright, ty and mypy are clean on the changed files.
Live checks for the headed tester
Mock sidebar hooks fix (2e2a173): in the URP path, a Record click now counts as taken as soon as the label leaves Record or Stop is enabled. Before this, G4's stub auto-stop could send the take before any poll saw Stop Rec, so the fallback started a second take. Master never caught it because URP wait_idle reads "Stop off + Send on" as idle, and Stop used to be greyed out during takes.
CI on 2e2a173: PR CI 37492341929 passed; mock sidebar 37492364772 passed (111 passed, 0 failed).