Blog ยท release
Latch 0.22.0
Today's mantra, voiced on your own box (#45). No migration. The voice is opt-in.
- ๐ Today's mantra. The Handler's mantra of the day, spoken: a 3โ5 minute track of it over a
quiet bed, heard five times with room to say it back, one affirmation, and an opening and a
close. Two a day: wake rises at the end with a bright tone, and bed settles and fades to
silence. On
/trance/mantra, the Trance page and the dashboard card. The Handler page's mantra gains ๐ play it. The words stay in the Handler's library; only the ritual moved. - Played to the end, it counts as recited. Judged on the audio the player actually produced
(clamped to the wall clock, within 5 s of the end), never on the page's "completed". Once a
day, and only a track of the day the sit is on. I said it and
!recitestill count. - ๐ด Not the bed one in restrictive gear. Refused on the server whatever the page offered, and the refusal names the wake one.
- The voice:
latch-voice, a second container (COMPOSE_PROFILES=voice). It runs Kokoro-82M on the CPU, with ffmpeg for the mix and the MP3, so Latch's own image stays ffmpeg-free. It publishes no port, sits on an internal-only network, and its model is baked in at build time: it has no internet, and Latch reaches it by name. The address (trance.voice_url) must resolve to this machine or your network, and is checked on every call. Trance now declares that egress, and the footer shows it. Measured on a 6-core pod: ~25 s per 4-minute track, ~1.4 GB peak, handed back after each render (the model runs in a child process that exits). The binaural offset survives the encoder: decoded, L 180.00 / R 186.00 Hz (LAME's joint stereo is off). - Rendered ahead at 03:45, both slots, three tries a day 30 minutes apart, kept 14 days. A sit never waits on a model.
- ๐ด The voice is chosen by ear first. Nothing renders until you pick one of three candidate voices, each rendered as a whole wake track at the level it plays.
- Blind is loud. A failed render says so with the reason and offers read-and-recite. A render of a mantra that has since changed is called stale and isn't offered. Yesterday's file is never played as today's. Render today's again re-renders either.
- Optional: open with today's line from your AI Handler (
trance.mantra_ai_line), never a masked one. Optional: the chat bot posts the wake track in your room at wake time, once a day, asm.audio(Post today's mantra audio on/consent, off by default). That putsGET /api/v1/bot/mantrain the bot token's scope, and/bot/todaygainsmantra_audio({ready, due, seconds},nullwhile off). Paused, nothing goes. A post is not a recite. - New settings:
trance.voice_url,trance.mantra_voice,trance.mantra_wake(07:00),trance.mantra_bed(22:30),trance.mantra_minutes(4),trance.mantra_ai_line(0).