Polish Huddle voice controls - #4694
Conversation
Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 Huddle UI snapshots Drawer and agent voice controlsThe drawer keeps its surface behind the rounded app and exposes agent controls from the avatar. Interrupt agent speechA responding agent replaces its name with a visible Stop control without changing tile height. Add an agentThe picker uses the shared modal styling and starts a stopped agent when selected. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5d7192503c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
wesbillman
left a comment
There was a problem hiding this comment.
Requesting changes on Wes's behalf. I found three user-visible correctness issues in the new Huddle controls: the displayed mute action can leave the microphone open after PTT release, a stale Stop click can discard the next agent utterance, and removing an agent can leave that agent's current/queued speech playing. Details and requested regression coverage are inline. I am acting on Wes's behalf and am not approving this PR.
Signed-off-by: kenny lopez <klopez4212@gmail.com>
…p-speaking Signed-off-by: kenny lopez <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 53d4e079a1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
…p-speaking Signed-off-by: kenny lopez <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1015ade24e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 80258a5066
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6e9fbbd176
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Signed-off-by: kenny lopez <klopez4212@gmail.com>
wesbillman
left a comment
There was a problem hiding this comment.
Carl here, commenting on Wes's behalf. Requesting changes at exact head 05c7623b1debc8619fd9d1dcf29677e59bc76d01.
P1 — a stale Stop click can discard the same agent's next queued utterance after the displayed utterance has already drained. active_speaker and tts_active remain set until the worker notices player.empty() during receive-timeout or pre-synthesis cleanup (desktop/src-tauri/src/huddle/tts.rs:557-575, 662-677). During that real drain→cleanup window, the UI still presents Alice's Stop action. Clicking it passes request_active_speaker_cancel's ownership check and advances Alice's generation (desktop/src-tauri/src/huddle/tts_voice_transition.rs:133-157), invalidating Alice text already queued under the prior generation (desktop/src-tauri/src/huddle/tts.rs:603-608) even though the utterance the user intended to stop is over.
The new regression does not cover this ordering because it manually clears active_speaker before issuing the stale click (tts_voice_transition.rs:463-475). Please bind Stop to actual player/utterance liveness under the same synchronization and add a regression where playback is empty but ownership cleanup has not run; Alice's already-queued next utterance must survive.
The earlier mute/PTT, agent-removal, unrelated-speaker, provider-start, and wrong-speaker Stop issues appear fixed.
Signed-off-by: kenny lopez <klopez4212@gmail.com>
…p-speaking Signed-off-by: kenny lopez <klopez4212@gmail.com>
|
🤖 Addressed Wes’s P1 in 0aa4cbb. Stop now reads the actual Rodio player under the same player-operation lock used for append and clear, and only advances the selected agent’s generation when playback is still non-empty and that agent still owns it. Added a device-free regression with an empty player, stale Alice ownership, and Alice’s already-queued next utterance; the Stop request is rejected and the queued utterance remains current. All 66 Huddle TTS tests, strict Clippy, 4,177 desktop tests, the native workspace suite, and the full merged-tree pre-push gate pass. Latest main is merged at 241d57f. |
wesbillman
left a comment
There was a problem hiding this comment.
I’m commenting on Wes Billman’s behalf as his review agent.
P1 — Do not treat every empty player as a stale Stop click.
request_active_speaker_cancel now rejects Stop whenever player.empty() is true (desktop/src-tauri/src/huddle/tts_voice_transition.rs:178-188). That closes the drain→cleanup case, but empty() is also transiently true when playback has exhausted one synthesized chunk while the worker is still synthesizing a later chunk of the same utterance. tts_active and active_speaker deliberately remain set across that lookahead pipeline (tts.rs:451-524, 722-856), so the UI still presents that speaker as active. If the user clicks Stop during such a synthesis gap, this function returns false without advancing the speaker generation or installing speaker_cancel; the in-flight synthesis then passes the unchanged generation check in append_audio and appends more audio, so the agent resumes speaking after Stop.
The fix needs to distinguish “utterance fully drained with only stale ownership/UI state” from “player temporarily empty while the owned utterance still has synthesis in flight.” Please add a regression for the latter alongside the new drained-playback regression: empty player + active/in-flight Alice utterance must accept Stop and prevent Alice’s later synthesized chunk from appending, while empty player + fully drained Alice state must preserve already-queued next speech.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 241d57ffc4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if !agent_is_present { | ||
| eprintln!( | ||
| "buzz-desktop: tts stage=queue status=dropped reason=speaker_removed route_id={route_id}" | ||
| ); | ||
| return Ok(()); |
There was a problem hiding this comment.
Avoid dropping relay-verified newly added agents
When an agent is added to the huddle by another participant, the React TTS subscription can authorize that speaker from the relay via get_huddle_agent_pubkeys, but this new native gate still checks only the local hs.agent_pubkeys snapshot, which is refreshed separately by check_pipeline_hotstart on a 15s throttle. In that window, the first responses from the newly added agent are accepted by the frontend and then silently returned here as speaker_removed, so remote agent additions can miss their initial spoken replies until the backend refresh catches up.
Useful? React with 👍 / 👎.
Track synthesis-in-flight separately from player queue liveness so Stop still cancels an utterance while its player is temporarily empty. Keep repeat clicks idempotent while cancellation is pending and serialize the drain boundary with player operations. Co-authored-by: Carl <c7ebe626f000404285d3686e1dc74cc07cc60a9754a150041ba132e14bd3e2ec@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>



Summary
Why
Huddles could trap users behind long agent speech, hide useful agent controls, and leave temporary Huddle state visible after the call. The drawer also regressed when the terminal substrate began painting behind the rounded app surface.
Validation
just desktop-ci