v0.13.2 - Voice language consistency, audited boundaries, and optional Pocket TTS
Provider-neutral voice language consistency, audited error boundaries,
and optional Kyutai Pocket TTS support.
🐛 Fixed
LocalSTTAdapter.transcribe()now acceptslanguage_code, matching
GoogleSTTAdapterandAssemblyAISTTAdapter, and reduces a BCP-47 tag
to the bare language identifier faster-whisper expects (es-ARbecomes
es). The historicallanguagename remains a compatibility alias.
When both names are present, equivalent primary subtags are accepted
and a real conflict raises a structured configuration error instead of
silently allowing one spelling to overwrite the other.AzureTTSAdapterandAzureSTTAdapternow acceptlanguage_codeat
construction and per call. A call such astranscribe(..., language_code="es-AR")reaches Azure aslanguage=es-ARinstead of
being silently discarded in favor of the configured default.- The canonical spelling covers every official STT adapter that offers
language selection. Deepgram acceptslanguage_codeat construction
and per call; Gladia and hosted Whisper accept it per call. Whisper
reduces BCP-47 tags to the primary language identifier its provider
expects. - The historical
languagespelling remains a compatibility alias
where it already existed. Equivalent effective tags are accepted;
conflicts raise a structuredSETTServiceAdapterErrorwith
adapter.language_arguments_conflictbefore provider work. CartesiaTTSAdapterjoins Azure, Google, and LocalTTS in accepting
per-calllanguage_code, with the same compatibility and conflict
behavior.LocalTTSAdapternow normalizes failures raised while creating the
engine, reading voice metadata, or applying voice properties. These
paths no longer leak provider exceptions outside SETT's error
hierarchy.- pyttsx3 language matching now understands the control-byte prefix
emitted by older eSpeak metadata and underscore-separated locale tags.
Thelocal-ttsextra now requires pyttsx3 2.99 because pyttsx3 2.90
does not expose SAPI5 language metadata on Windows, making honest
language selection impossible there. - Local TTS and STT paths preserve cancellation and deadline exceptions
after provider work instead of translating them into service-adapter
failures. ContextAnalyzer.EMOTIONAL_RISK_MODIFIERSis now an immutable
mapping. One analyzer instance can no longer change the risk score
produced by every other instance through shared class state.
✨ Added
LocalTTSAdapter.synthesize()now accepts an optional
language_codekeyword argument, matchingGoogleTTSAdapter. Without
an explicitvoice_id, it looks for an installed host voice whose own
metadata names the requested language and leaves the current voice
untouched when none does. It deliberately does not guess from
free-form voice identifiers.PocketTTSAdapteradds optional Kyutai Pocket TTS 2.1 support
through the existingTTSBasecontract. It lazily loads a
caller-selected language and voice, accepts the conditioning forms
supported by Pocket TTS, and returns mono PCM16 WAV bytes. The adapter
declares six language families and voice cloning.- Pocket TTS generation is exposed honestly as non-streaming because
TTSBase.synthesize()returns one complete byte payload. The
underlying model's streaming API does not change SETT's current
contract. - One adapter instance serializes model loading, voice conditioning,
and generation because Pocket TTS documents its generation methods as
not thread-safe. The package and model remain optional; first use can
download model weights or catalog voices, while cached assets can
synthesize without a remote service.
🧹 Maintenance
- SETT now owns an explicit Ruff 0.16.0 policy in
pyproject.toml.
Repository validation no longer depends on whichever default rule set
an installed Ruff version happens to provide. The full tree passes
with zero findings. - Imports, annotations, unused test values, broad exception
assertions, intentional Unicode fixtures, and context-manager
structure were cleaned across the repository. Deliberate
audit-boundary catches remain in place with narrow inline
explanations. - Thirteen test modules now use stable, version-independent filenames.
Their names describe the contract under test, so future releases
update the same files instead of creating parallel version-labelled
suites. LocalSTTnow delegates language aliases, conflicts, primary-subtag
handling, and lowercase normalization to the shared_language.py
resolver instead of maintaining a second copy of the same rule.
📄 Documentation
README.mdanddocs/getting_started.mdnow document source
installation instead of presenting SETT as available from PyPI, where
it is not published.- Removed the unpublished draft Convention #24, which proposed a
repositorychecksums.txtpractice that was never present in the
released v0.13.1 archive. This entry records the governance edit
without presenting the draft as a released guarantee.
✅ Compatibility
- No public symbol was removed or renamed. Existing callers using
languagecontinue to work where that spelling already existed;
language_codeis the canonical spelling for provider-neutral call
sites. - The 1,003 tests of v0.13.1 pass unmodified.
- The complete v0.13.2 suite passes with 1,038 tests, 0 skipped.
- The private companion-assistant application's suite (1,162 tests)
passes against this source release with zero application code
changes. - SETT keeps zero mandatory dependencies.
pocket-ttsis available as
an opt-in extra, included only in theallextra.
⚠️ Versioning decision
PocketTTSAdapter is additive public API, which would ordinarily place
it in a minor release under this project's own versioning convention.
This is an explicit, one-time exception: Pocket TTS became known only
days before this release closed and addressed an immediate need for a
local CPU TTS option. Keeping the completed work in the same patch
avoided manufacturing two releases for one review cycle. This does not
redefine the stable API boundary and does not relax the default rule
for future additive public APIs.
💖 Sponsors
Sponsors:
eight tiers from a symbolic $1 up to logo placement on 4humanityAI.com,
with explicit limits on what sponsorship does and does not buy.
See the complete itemized history in
CHANGELOG.md.