Skip to content

v0.10.0 — clearing the board: verified renders, windowed transcription, honest usage

Latest

Choose a tag to compare

@arcaputo3 arcaputo3 released this 14 Aug 20:21
1f0d066

What's Changed

A board-clearing release: fourteen of the fifteen open issues, most of them the operational
costs that agents using this tool had been absorbing by hand. Long audio no longer truncates
silently, podcast renders can now prove they contain the words you wrote, ElevenLabs reports what
it spent, batch inputs may span directories, and the simulated-podcast producer steers the turns
it was previously leaving generic. Plus one data-loss bug.

Features

  • Long files are windowed for transcription instead of truncating. A 13-minute mp3 came back
    cut off around 10.5 minutes with no error, and another run silently dropped a stretch from the
    middle; 30 minutes failed outright. Over 8 minutes, the file is now cut into overlapping 90s
    windows at a 75s stride, transcribed concurrently, and stitched — chunked: true and a
    windows list make coverage inspectable rather than assumed. Do not pre-cut long audio
    yourself any more. (#64)
  • podcast generate --verify transcribes each rendered unit, checks it against the script,
    and re-renders what is missing, once. TTS drops segment tails and whole short segments at
    random with no error, and transcript is only an echo of your input — so this replaces an
    external QC discipline that cost a median of three renders per episode. A segment failing twice
    is reported, not re-rendered a third time. (#65)
  • ElevenLabs reports characters submitted, per provider and model, on both audio speak and
    podcast generate. sanzaru capabilities --quota reads the remaining monthly allowance
    without spending any of it. On a 10,000-character tier this was the number you previously had
    to count by hand. (#66)
  • Batch inputs may span directories. audio transcribe a/ep.mp3 b/window.mp3 used to exit 2;
    each input is now anchored and validated under its own parent. Only a shared basename is
    still refused. (#62)
  • ActBrief.closing_note directs the turn that lands an act without spending the
    max_turns - 1 index, which was unavoidably a takeover. Talking points now also schedule across
    the extension turns instead of leaving them on a generic anti-recap note. (#61)
  • PodcastScript requires only speakers and segments. id, speed, instructions,
    title and the whole config block default, and an invalid script reports every problem at
    once rather than one per round trip. (#57)

Fixes

  • audio compress -o destroyed the input when the file was already under the size budget:
    the service wrote nothing and the CLI moved the source away. The documented "compress first,
    then transcribe" workflow therefore lost exactly the originals that did not need compressing.
    (#60)
  • An act is now bounded in wall clock against the Realtime API's 60-minute connection close,
    landing early with stop_reason: "wall_clock" rather than risking the loss of everything
    recorded so far. QC also flags capped_short, the undershoot stop_reason that #46 exposed and
    nothing consumed. (#63)
  • result.output_file names the file that actually exists, including when -o renamed it or it
    was staged under a temporary name. (#56)
  • Dialogue mode documents its retry trade, and its 2000-character limit is presented as the
    planning number it is. (#58)

Internal

  • New audio/verification.pywords, similarity, transcribe_bytes — shared by realtime QC,
    the podcast verify pass, and window merging, instead of three copies that would drift. (#64)
  • AudioProcessor gained audio slicing; TranscriptionService gained its first tests. (#64)

⚠️ Behavior changes

  • Duplicate speaker ids are now a hard error. Previously the last one silently won. (#57)
  • The dry-run cost projection rises slightly. turn_count and the text_in term project
    against the extension ceiling rather than the planned max_turns — the same recording, a more
    honest number, and you no longer have to inflate max_cost_usd by hand. (#61)
  • synthesize_speech returns a SpeechResult rather than bare bytes. Internal, but it is the one
    signature change here. (#66)

Still open: #37 (async job mode for podcast generate), blocked on the official mcp SDK
shipping a stable tasks API. See docs/async-task-tracking.md.

Full Changelog: v0.9.1...v0.10.0