feat: generative background music & notification sound system#3588
feat: generative background music & notification sound system#3588ttmouse wants to merge 1 commit into
Conversation
- Token-driven generative music engine with 4 presets (Classic/Ethereal/Digital/Retro) - Notification sound system with Success and Attention events - 5 sound effects per event (synthesized + WAV files from Mixkit) - Settings UI for sound/music preferences with preview buttons - agent:turn-done backend event for frontend sound triggering
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 85159f971a
ℹ️ 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".
| // Emit a dedicated "generation complete" event so the frontend can play a | ||
| // success sound without mis-firing on tab switches. | ||
| if e.Kind == event.TurnDone && s.ctx != nil { | ||
| runtime.EventsEmit(s.ctx, "agent:turn-done") |
There was a problem hiding this comment.
Carry turn errors into the chime event
When a run fails, TurnDone carries Err (documented in internal/event/event.go), but this new side-channel drops the payload and App.tsx plays playSuccessChime() for every agent:turn-done. In that failure scenario the UI still emits the success chime, unlike the existing notification path that distinguishes failed turns; include the error/status or consume the typed event so failures can be handled separately.
Useful? React with 👍 / 👎.
| onChange={(e) => { | ||
| const next = e.target.value as GenerativePreset; | ||
| setGenMusicPreset(next); | ||
| setGenerativePreset(next); |
There was a problem hiding this comment.
Honor music changes during active turns
When the user changes this setting while a turn is already running, this only updates localStorage; the App.tsx effect that starts/stops the engine is keyed solely on state.running, so choosing Off (or switching presets) does not affect the currently playing engine until the turn ends. Stop the singleton immediately for off, and apply the new preset to the running engine for non-off choices, so the setting takes effect during active generations.
Useful? React with 👍 / 👎.
| if (state.running && isGenerativeMusicEnabled()) { | ||
| generativeMusic.start(); |
There was a problem hiding this comment.
Track background tab runs for generative music
This starts the music engine from the currently active tab's state.running, but the desktop supports multiple tabs whose controllers keep running after the user switches tabs. If tab A is generating and the user switches to idle tab B, the active state becomes false and this effect stops the music even though an agent is still generating; conversely token events are subscribed globally. Base the engine on the tab list/controller running state for any running tab, or filter token playback to the same tab state.
Useful? React with 👍 / 👎.
esengine
left a comment
There was a problem hiding this comment.
The note engine is competent and this can land as an opt-in extra, but defaults and assets block it:
- Everything must default OFF:
readPresetPref()falls back to"ethereal"(music plays out of the box), andSoundWavPrefhas no"off"member — the turn-done and AskCard chimes can't be disabled at all. agent:turn-doneis emitted without a tab id and the handler plays for any tab — background tabs chime over the active one. Scope it; same for the per-token note subscription.- The 4 embedded WAVs are ~1.5 MB inside the binary for every user. Convert/trim to OGG (~100–150 KB) or go synth-only, and add the Mixkit license attribution.
- Prefs belong in desktop settings (config) like every other setting, not localStorage — they currently don't sync and reset per WebView profile.
- Comment policy: the Chinese file-header essays and
──section banners need to go (see CLAUDE.md).
Plus a rebase onto the post-#3752 SettingsPanel.
生成式背景音乐 & 通知音效系统
生成式背景音乐
通知音效
后端改动