aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* tts: bound the audio cache and request lengthsalmonik4 days1-5/+86
|
* autocomplete: bound the in-memory cachessalmonik4 days1-6/+24
|
* events: never join or move voice just to play TTSsalmonik4 days1-8/+16
|
* recording: keep one buffer per guildsalmonik4 days3-34/+41
|
* triggers: scope groups to the guild that created themsalmonik4 days4-24/+64
|
* cron: scope jobs to the guild that created themsalmonik4 days2-19/+47
|
* commands: gate admin, trigger, cron and recording behind permissionssalmonik4 days4-14/+18
|
* utilities: sanitize filenames and isolate temp operationssalmonik4 days1-48/+105
|
* yt-dlp: ignore configs and stop option injectionsalmonik4 days2-3/+16
|
* copyparty: never send the password to foreign hostssalmonik4 days4-28/+165
|
* say: do not abort if the ephemeral ack is already gonesalmonik6 days1-1/+3
|
* cron: keep scheduled audio silentsalmonik6 days3-3/+12
| | | | | | | Add a per-track silent flag. Cron already uses play_now (interrupt the current track), but play_next_locked still announced the track to the last known text channel; suppress playing and failure announcements for silent tracks, including when a cron track fails to prepare.
* say: post text as a normal message after an invisible acksalmonik6 days1-7/+15
| | | | | | Acknowledge the interaction with a zero-width ephemeral reply, delete it, then send the text through ChannelId::say so it lands as a normal channel message instead of an interaction reply.
* docker: bake espeak-ng data for Piper TTSsalmonik11 days5-9/+47
| | | | | | | | | | | espeak-rs-sys installs espeak-ng-data into the build tree and compiles that path in as the default, so the runtime image failed with 'phontab: No such file or directory'. Copy the data from the builder to /usr/share and point PIPER_ESPEAKNG_DATA_DIRECTORY there; compose overrides the host path from .env. Also trim trailing slashes from Copyparty base URLs, document that env_file changes need --force-recreate, and clean inline comments in .env.example.
* contextual play should add to the last in the queuesalmonik12 days1-8/+6
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* docker: build and run on Debian trixiesalmonik12 days4-0/+156
| | | | | | | | | | | Add a multi-stage image that compiles inside Debian trixie and runs on the same glibc/libssl/libopus, avoiding the Arch-built binary failing on Debian. The runtime image installs ffmpeg, qalc, the shared libraries, and the latest yt-dlp zipapp, and runs as uid 1000. compose.yaml mounts data/ and piper/, overrides TTS_MODEL_PATH for the container layout, and builds with host networking because the default Docker bridge DNS cannot resolve crates.io or deb.debian.org on this host.
* music: group playback commands under /musicsalmonik12 days5-31/+66
| | | | | | | | | Graduate grajcuj/skip/queue/stop/join into the /music parent and drop the top-level names. On startup, reconcile global slash commands and delete any that are no longer registered, since Discord otherwise keeps stale commands after a rename or move. Docs updated for the new command layout and queue semantics.
* music: add per-guild queue with now/next/last, skip and queuesalmonik12 days6-269/+790
| | | | | | | | | | Tracks are queued in memory per guild, defaulting to append (last). Playback auto-advances on TrackEvent::End/Error with a per-track token so manual stops and skips cannot double-advance. /music queue shows the current track followed by pending items. /stop clears the queue. Cron audio now goes through the same MusicState instead of poking the track-handle map directly.
* silence songbird udp_rx decode noisesalmonik2026-09-091-1/+6
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* record: 2x gain on mp3 encodesalmonik2026-09-091-0/+5
|
* test recorder ring semantics; extract mix_ticksalmonik2026-09-091-50/+187
|
* wire recording into voice manager, config, events, /record commandsalmonik2026-09-098-5/+158
|
* first draftsalmonik2026-09-092-0/+410
|
* /grajcuj plays video-like extensions toosalmonik2026-09-092-9/+9
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* message-contextual /grajcujsalmonik2026-09-093-13/+58
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* assistant replies to the messagesalmonik2026-09-093-4/+4
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* make /grajcuj w\ compress finally work as compressing a file and thensalmonik2026-09-094-48/+132
| | | | | | /grajcuj'ing Signed-off-by: salmonik <salmonik@tuta.io>
* feat: piper now not a subprocess, cache system for TTSsalmonik2026-09-0512-175/+762
|
* remove ` from TTS and make events use lang.rssalmonik2026-09-032-31/+108
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* fix: cosmetic changessalmonik2026-09-021-50/+47
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* fix: enable wav supportsalmonik2026-08-192-7/+38
|
* feat: leaderboadssalmonik2026-08-197-3/+523
|
* fix: clear voice_activity upon startingsalmonik2026-08-191-0/+4
| | | | this lets stale records from abrupt stopping be deleted
* fix: Various cron fixessalmonik2026-08-195-17/+73
| | | | | Not saving full URL Not using autocompletion content, just label
* feat: local TTS via piper subprocess with Google fallbacksalmonik2026-08-1813-95/+308
| | | | | | | | | | | - New src/tts.rs: centralize TTS in synthesize(config, http_client, text) Piper subprocess primary, Google Translate fallback on error/missing - TTS_MODEL_PATH/TTS_VOICE env config (defaults to pl_PL-bass-high) - Fix Unknown interaction errors: spawn play_tts_in_channel in background so voice-state TTS no longer blocks the shard event loop (3s Discord limit) - Best-effort confirmation replies in /tts to prevent error cascade - Custom on_error handler: graceful interaction-expired error handling - Comprehensive tracing logging (engine, model, duration, stderr)
* fir auto completion and send file in the response body upon grajcuj filesalmonik2026-07-316-22/+69
|
* fix: auto completion timing out before ready + fix preexisting warnssalmonik2026-07-3012-129/+333
|
* fix assistant and senatorsalmonik2026-07-135-74/+117
| | | | Signed-off-by: salmonik <salmonik@tuta.io>
* make cron follow local time zonesalmonik2026-07-101-11/+18
| | | | Signed-off-by: salmonik <raisersoft@proton.me>
* fix cron double firesalmonik2026-07-092-14/+46
| | | | Signed-off-by: salmonik <raisersoft@proton.me>
* search for mp4's toosalmonik2026-07-091-1/+5
| | | | Signed-off-by: salmonik <raisersoft@proton.me>
* truncate search resultssalmonik2026-07-083-16/+19
| | | | Signed-off-by: salmonik <raisersoft@proton.me>
* remember links during audio file completionsalmonik2026-07-083-6/+8
| | | | Signed-off-by: salmonik <raisersoft@proton.me>
* rename the project to what it should be namedsalmonik2026-07-082-4/+4
|\ | | | | | | Signed-off-by: salmonik <raisersoft@proton.me>
| * Merge pull request 'feat: add local API support for OpenAI compatible APIs' ↵salmonik2026-06-035-136/+122
| |\ | | | | | | | | | | | | | | | (#6) from dev into main Reviewed-on: https://codeberg.org/salmonik/senator-sperma/pulls/6
| | * feat: add local API support for OpenAI compatible APIssalmonik2026-06-035-136/+122
| | | | | | | | | | | | Signed-off-by: salmonik <raisersoft@proton.me>
* | | OPEN THE RUST GATESsalmonik2026-07-0884-6659/+11991
|/ / | | | | | | Signed-off-by: salmonik <raisersoft@proton.me>
* | Merge pull request 'Voice related fixes, alongside simplifying assistant' ↵salmonik2026-05-2120-688/+532
|\| | | | | | | | | | | (#5) from dev into main Reviewed-on: https://codeberg.org/salmonik/senator-sperma/pulls/5
| * Fix voice reconnect race: reuse VoiceClient instead of destroying itsalmonik2026-05-211-11/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The stale-connection path was calling _remove_voice_client() then creating a brand-new VoiceClient via channel.connect(). This created a race: VOICE_SERVER_UPDATE (triggered by Discord when the user joins voice) arrives between the destroy and the fresh-connect, gets consumed by the old client, and the new client never receives it — causing a 10s timeout waiting for got_both_voice_updates. Fix: after disconnect(), call vc.connect() on the same VoiceClient instance. The disconnect resets the state machine to 'disconnected' but the same VoiceConnectionState processes any events that arrive between disconnect and reconnect, so the state machine correctly reaches got_both_voice_updates.
| * make the assistant simplersalmonik2026-05-211-90/+21
| | | | | | | | Signed-off-by: salmonik <raisersoft@proton.me>