Skip to content

Add sounds for completed turns and user input requests#3892

Open
jakeleventhal wants to merge 5 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/add-turn-status-sounds
Open

Add sounds for completed turns and user input requests#3892
jakeleventhal wants to merge 5 commits into
pingdotgg:mainfrom
jakeleventhal:t3code/add-turn-status-sounds

Conversation

@jakeleventhal

@jakeleventhal jakeleventhal commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Screen.Recording.2026-07-11.at.6.57.13.PM.mov
  • add Cuelume's synthesized success cue when a turn completes
  • add the bloom cue when a thread begins requesting user input
  • listen to global thread-shell transitions so background threads are covered
  • suppress sounds during initial thread hydration and avoid replaying unchanged states

User impact

Users receive an audible signal when agent work finishes or pauses for input, including when the affected thread is not currently open.

Validation

  • vp test apps/web/src/interactionSounds.test.ts
  • vp check
  • vp run typecheck

Note

Low Risk
UI-only feedback with conservative hydration guards; no auth, data, or server behavior changes beyond a persisted client preference defaulting to on.

Overview
Adds optional audible feedback when agent work finishes or pauses for the user, including for threads that are not currently open.

A root-level InteractionSoundCoordinator watches global thread shells and uses cuelume to play a success cue when a turn newly completes and bloom when a thread starts needing user input or approvals. interactionSounds compares prior vs current per-thread snapshots so cues are not replayed on unchanged state, and defers playback until client settings have hydrated so initial load does not spam sounds.

enableCompletionSounds is added to client settings (defaults on), with a Completion sound toggle in General settings and restore-defaults support. Desktop client settings tests are updated for the new field.

Reviewed by Cursor Bugbot for commit ac5b546. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Add sounds for completed turns and user input requests

  • Adds a cuelume-based InteractionSoundCoordinator component in routes/__root.tsx that plays a success sound when a thread's latest turn completes and a bloom sound when a thread starts requesting user input or approvals.
  • Introduces helper utilities in interactionSounds.ts to snapshot thread state and derive sound cues by comparing prior and current thread states.
  • Adds an enableCompletionSounds boolean field to ClientSettingsSchema (defaulting to true) and exposes a toggle in the General settings panel.
  • Sound playback is suppressed until settings finish hydrating to avoid spurious sounds on initial load.

Macroscope summarized ac5b546.

- Add interaction sound cue detection with hydration-safe tests
- Play bloom and success cues from the web app
@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 06cb2924-dd17-4d11-a9a4-05c443f5ce17

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list. labels Jul 11, 2026
@jakeleventhal
jakeleventhal marked this pull request as ready for review July 11, 2026 18:06
@macroscopeapp

macroscopeapp Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

This PR adds a new feature (completion sounds) enabled by default for all users, with a new external dependency. New user-facing features warrant human review even when well-implemented.

You can customize Macroscope's approvability policy. Learn more.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:M 30-99 changed lines (additions + deletions). labels Jul 11, 2026
Comment thread apps/web/src/routes/__root.tsx
Avoid advancing known thread sound state during settings hydration so turn completion and input cues are not dropped before the preference is ready.

Co-authored-by: Cursor <cursoragent@cursor.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9626d08. Configure here.

if (latestTurn?.state !== "completed" || latestTurn.completedAt === null) {
return null;
}
return `${latestTurn.turnId}:${latestTurn.completedAt}`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interrupted finished turns skip sound

Medium Severity

completedTurn only treats latestTurn.state === "completed" as finished. Shell snapshots often end turns as interrupted with a non-null completedAt (session teardown races and interrupt handling), which resolveThreadAwarenessPhase already counts as completed. Those finishes never emit the success cue.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9626d08. Configure here.

merged.set(key, state);
}
}
return merged;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hydration freeze drops mid-window transitions

Medium Severity

While settings hydrate, captureThreadSoundStateWhileSettingsHydrating never updates baseline state for threads already in the map. If a turn completes and a new one starts, or pending input appears then clears, before hydration ends, the first post-hydration diff matches the frozen baseline and no success or bloom cue plays.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9626d08. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9626d0808d

ℹ️ 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".

const previous = previousStateRef.current;
if (completionSoundEnabled && previous !== null) {
for (const cue of deriveInteractionSoundCues(previous, threads)) {
play(cue);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Unlock audio from a user gesture before background cues

In browsers that require AudioContext.resume() to happen during a user activation, the first call to play() here runs later from a shell-state effect, not from the click/keydown that submitted the prompt. If no prior Cuelume sound has already unlocked the shared context, completion/input cues can be silently blocked and never heard; prime or resume the sound engine from an explicit user interaction before relying on background notifications.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ac5b546dc8

ℹ️ 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 (latestTurn?.state !== "completed" || latestTurn.completedAt === null) {
return null;
}
return `${latestTurn.turnId}:${latestTurn.completedAt}`;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Track completed turns without mutable timestamps

When a provider turn.completed is processed, ProviderRuntimeIngestion emits thread.session-set while CheckpointReactor can later emit thread.turn-diff-completed for the same turn; the projector/reducer update latestTurn.completedAt from those events. If thread.session-set settles the turn first, this timestamp-based key changes again when the checkpoint event arrives, so deriveInteractionSoundCues treats the same completed turn as a new completion and plays a second success cue. Use stable turn identity, or separately remember notified turn ids, so checkpoint timestamp corrections do not replay completion sounds.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant