May 14, 2026

Voice Hardening, Ability Recall, Dashboard Fixes

TTS and STT get crash and hallucination fixes while a new review_transcript ability gives agents memory of subagent work

Today was about closing gaps that only show up under real use — a voice pipeline that could crash on long text, a dashboard that lied about which model was busiest, and agents that couldn’t see what their own subagents had just done. None of these are glamorous, but they’re the difference between a demo and a tool you trust.

The voice pipeline got two real fixes. Text-to-speech was hitting Kokoro’s 510-phoneme hard limit on longer replies and crashing outright, so I added a segmentation pass that splits text into chunks under 320 characters on sentence, then clause, then whitespace boundaries before each synthesis call — chunked audio gets stitched back together with short silence pads, and the common short-reply path is untouched. Speech-to-text had the opposite problem: the known Whisper/Moonshine failure mode where silence or noise sends the model into a repetition loop. A dedup pass now collapses consecutive identical 2-6 word n-grams down to two copies, applied per-chunk and again on the final joined transcript, while leaving legitimate single-word repetition (the kind people actually say) alone. Once both fixes were proven, I went back and tightened the TTS segmentation into a single regex split — the sentence-then-clause cascade was 76 lines of ceremony doing the same job as one line, and all 28 tests still pass.

On the observability side, two dashboard bugs got fixed because they were actively misleading. “Most active model” was querying the raw call log with no time-window filter, so it always showed the lifetime leader no matter what window you selected — now it’s derived from the already-filtered result set, so the number on screen matches the window you picked. Separately, the usage chart crashed on a second render because it replaced its own SVG element via outerHTML, silently dropping the id the next render needed to find it — swapped to updating attributes in place instead. Neither bug was visible on first load, only on interaction, which is exactly the kind of thing that erodes trust in a dashboard if it sits unfixed.

The other piece was closing a real blind spot: subagents do work and hand back a result, but that result was invisible to everything except the immediate parent. I added a review_transcript ability that searches transcript rows within a time window around a given timestamp, with a flag to pull in the subagent channel — so an agent can now go back and recover what a subagent actually did, not just what it was told. It’s wired into the always-available tool set for both the main and background processors, since both need the same recall.

None of this changes what Chalie can do — it changes whether what it already does holds up under pressure. Voice that doesn’t crash on a long answer, a dashboard that tells the truth about the selected window, and agents that can actually remember their own subagents’ work are the unglamorous prerequisites for everything more ambitious that’s coming.

  • TTS now chunks text under 320 characters before synthesis, preventing phoneme-overflow crashes on long replies
  • STT deduplicates repeated 2-6 word n-grams to suppress the known hallucination-loop failure mode
  • TTS segmentation refactored from a multi-tier cascade to a single regex split, cutting 76 lines with no behavior change
  • Observability’s “most active model” now respects the selected time window instead of showing the lifetime leader
  • Brain usage chart no longer crashes on re-render after a DOM-replacement bug dropped its element id
  • New review_transcript ability lets agents recover subagent channel results by timestamp