<feed xmlns='http://www.w3.org/2005/Atom'>
<title>senator-sperma/cogs, branch main</title>
<subtitle>Very big discord bot.
</subtitle>
<id>https://git.2137697.xyz/senator-sperma/atom?h=main</id>
<link rel='self' href='https://git.2137697.xyz/senator-sperma/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/'/>
<updated>2026-07-08T00:13:35Z</updated>
<entry>
<title>OPEN THE RUST GATES</title>
<updated>2026-07-08T00:13:35Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-07-08T00:13:35Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=cd8ed8bc5793985df2c1692072a932ceee517b95'/>
<id>urn:sha1:cd8ed8bc5793985df2c1692072a932ceee517b95</id>
<content type='text'>
Signed-off-by: salmonik &lt;raisersoft@proton.me&gt;
</content>
</entry>
<entry>
<title>Merge pull request 'Voice related fixes, alongside simplifying assistant' (#5) from dev into main</title>
<updated>2026-05-21T15:10:23Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-21T15:10:23Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=2e614665e0c62fe572b5af53a2a6be1116d66720'/>
<id>urn:sha1:2e614665e0c62fe572b5af53a2a6be1116d66720</id>
<content type='text'>
Reviewed-on: https://codeberg.org/salmonik/senator-sperma/pulls/5
</content>
</entry>
<entry>
<title>Fix voice reconnect race: reuse VoiceClient instead of destroying it</title>
<updated>2026-05-21T14:45:31Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-21T14:45:31Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=35545e30303faa517a98ec18c660e5f6c063c912'/>
<id>urn:sha1:35545e30303faa517a98ec18c660e5f6c063c912</id>
<content type='text'>
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.
</content>
</entry>
<entry>
<title>make the assistant simpler</title>
<updated>2026-05-21T14:38:01Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-21T14:38:01Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=e498df0647caa0360513da80fded4f5e5ea8cf2e'/>
<id>urn:sha1:e498df0647caa0360513da80fded4f5e5ea8cf2e</id>
<content type='text'>
Signed-off-by: salmonik &lt;raisersoft@proton.me&gt;
</content>
</entry>
<entry>
<title>Fix zombie voice client after gateway restart</title>
<updated>2026-05-20T15:19:11Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-20T15:19:11Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=f5af4c11645bb1ff3aa993fb9c3a29c4a01b40c3'/>
<id>urn:sha1:f5af4c11645bb1ff3aa993fb9c3a29c4a01b40c3</id>
<content type='text'>
- play_tts: run is_voice_client_alive() check regardless of is_playing()
  state. After a gateway restart, is_playing() can return True on a
  dead client, which previously bypassed the stale-detection guard
  (was: 'if is_connected and not is_playing')
</content>
</entry>
<entry>
<title>Fix stale-connection reconnect hang and TTS temp-file collision</title>
<updated>2026-05-20T15:08:40Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-20T15:08:40Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=8d35930871db37b1009275c423ce95ed72954613'/>
<id>urn:sha1:8d35930871db37b1009275c423ce95ed72954613</id>
<content type='text'>
- _ensure_voice_client: call _remove_voice_client() when cleaning up stale
  or disconnected clients so the fresh connect doesn't hang for 30s
  waiting for Discord's stale state to clear
- Reduce connect timeout from 30s to 10s for faster failure recovery
- vclogs.py: use a unique temp filename per TTS call (include timestamp)
  instead of relying on PID alone, preventing concurrent TTS calls from
  clobbering each other's files
</content>
</entry>
<entry>
<title>Redirect play_commands imports to cogs.voice, remove audio_playback shim</title>
<updated>2026-05-20T14:40:28Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-20T14:40:28Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=bdf93cbc700f6baa55a283300d5bd3d2e958bc69'/>
<id>urn:sha1:bdf93cbc700f6baa55a283300d5bd3d2e958bc69</id>
<content type='text'>
- Update play_commands.py to import get_voice_manager from cogs.voice
  instead of going through the audio_playback.py re-export shim
- Delete the audio_playback.py shim file entirely
- Update test_music_audio.py imports to use cogs.voice.VoiceManager
- Delete PLAN_VOICE_REFACTOR.md (plan is complete)
</content>
</entry>
<entry>
<title>Clean up consumers: replace polling with VoiceManager.play_source()</title>
<updated>2026-05-20T13:40:18Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-20T13:40:18Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=4663f260b55de0975661fda1c00f60d2ca6e4506'/>
<id>urn:sha1:4663f260b55de0975661fda1c00f60d2ca6e4506</id>
<content type='text'>
- cron.py: replace while-is_playing polling with VoiceManager.play_source()
- vclogs.py: replace while-is_playing polling with VoiceManager.play_source()
- stop.py: use VoiceManager.disconnect() instead of raw voice_client
- join.py: use VoiceManager.connect() instead of raw channel.connect()
- voice.py: add back join_by_channel_id() convenience method
- Tests: update for new VoiceManager method names and signatures
</content>
</entry>
<entry>
<title>Fix TTS and AI voice playback bugs</title>
<updated>2026-05-20T13:37:14Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-20T13:37:14Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=03b94f61318675f1df83d384670b506a0df6e118'/>
<id>urn:sha1:03b94f61318675f1df83d384670b506a0df6e118</id>
<content type='text'>
- tts.py _handle_voice_output: add missing voice_client.play() call
  via VoiceManager.play_source() — was creating the audio source
  and then doing nothing
- ai.py: use VoiceManager.play_source() instead of passing an
  FFmpegPCMAudio object to play() which expects a string path
</content>
</entry>
<entry>
<title>Fold AudioPlaybackManager into VoiceManager + Future-based play</title>
<updated>2026-05-20T13:36:17Z</updated>
<author>
<name>salmonik</name>
<email>raisersoft@proton.me</email>
</author>
<published>2026-05-20T13:36:17Z</published>
<link rel='alternate' type='text/html' href='https://git.2137697.xyz/senator-sperma/commit/?id=fbdfad855ab9a1233e286806439397729ba21226'/>
<id>urn:sha1:fbdfad855ab9a1233e286806439397729ba21226</id>
<content type='text'>
- Move all static helpers (validate_voice_channel, prepare_source,
  prepare_audio_source, etc.) from AudioPlaybackManager into VoiceManager
- Add _play_await() using asyncio.Future + after callback, replacing
  all polling patterns and the 5-second sleep hack
- Add play() high-level method and play_source() for pre-made sources
- Unify connection logic under single _ensure_voice_client()
- Remove dead Voice cog class and its setup()
- Gut audio_playback.py to a re-export shim
- Remove cogs.voice from main.py extensions
</content>
</entry>
</feed>
