feat(web): audible ping when an agent calls ping_user - #90
Merged
Conversation
Play a short synthesized two-tone sound whenever an agent invokes the ping_user tool, so the user stays aware of pings on any page. - sound.ts: playPing() via Web Audio (no asset, works offline, lazy AudioContext, resume-on-suspended for the autoplay policy). - usePingSound.ts: subscribes to the workforce-wide /api/home/stream and fires playPing() on task_events with kind "ping_user", deduped by id. - Mounted once in RootLayout so it fires regardless of the active route, not only on the home/chat view where useHomeStream lives. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Deploying openacme-ai with
|
| Latest commit: |
a99ad8b
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://b098447e.openacme-ai.pages.dev |
| Branch Preview URL: | https://worktree-ping-sound.openacme-ai.pages.dev |
Collaborator
|
Add in settings UI |
Per PR review — the audible ping was always-on with no way to mute it. Add a Sound card under Settings → Notifications with an on/off toggle plus a Test-sound button. The preference persists in localStorage (opt-out only; defaults on) and usePingSound reads it fresh at fire time, so muting takes effect immediately on any open tab. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
Author
|
Added a Settings toggle (f1a5823). New Sound card under Settings → Notifications: on/off toggle + a Test-sound button. Preference persists in localStorage (opt-out only, defaults on); |
baseUrl is deprecated for removal in TypeScript 7.0 (newer editor TS already surfaces the warning). Since TS 5.0, "paths" resolves relative to the tsconfig directory without baseUrl, so "baseUrl": "." is a no-op here. Removing it clears the deprecation; check-types passes unchanged for both apps. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.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.
What
Plays a short synthesized two-tone sound in the web UI whenever an agent invokes the
ping_usertool, so the user stays aware of pings on any page — not just the chat view.How
apps/web/app/lib/sound.ts(new) —playPing()via the Web Audio API. No audio asset to ship, works offline, lazyAudioContextwith resume-on-suspended to cope with the browser autoplay policy.apps/web/app/lib/usePingSound.ts(new) — subscribes to the workforce-wide/api/home/streamSSE channel and firesplayPing()ontask_events whoseevent.kind === "ping_user", deduped by event id (an SSE reconnect could redeliver).apps/web/app/routes/__root.tsx— callsusePingSound()inRootLayout, which wraps every route, so the sound is global rather than scoped to the home/chat page whereuseHomeStreamlives.Deliberately fires only on explicit
ping_userevents, not on every turn ending (that would be noisy).Verification
check-types+lintpass (also enforced by the pre-commit/pre-push hooks — 26 tests passed on push). Verified live in a browser against the~/.openacme-testslot on :3456:ping_userfilter +playPingcall./api/home/streamopens from the page.playPing()synthesizes audio without error, driven by the exact server wire-payload for aping_userevent; dedupe confirmed (same id doesn't replay).The server path (
ping_usertool → EventStore → broadcaster →streams.ts→ home stream) was confirmed by code inspection. A fully LLM-originated ping wasn't exercised because the test slot's Anthropic OAuth token is expired (a test-env issue, unrelated to this change).Note
First ping after a page load may be silent until the user has clicked once — inherent browser autoplay policy, not fixable in code.
🤖 Generated with Claude Code