- Python 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Review fixes (final review M8/M9): - M9: design/clone/speak on a real EngineAdapter now run via starlette run_in_threadpool so one synthesis no longer blocks health, the panel, or other requests. The deterministic MockAdapter stays inline (no model work to isolate). - M8: README updated to the v0.3.0 interface — design/clone return (bytes, metadata), speak receives a FrozenVoice, and clone requires a non-empty consent/rights field — with a breaking-change migration note. The consent requirement is an intentional voice-clone safeguard and is kept (this is the plugin fleet, not studio-dev's no-gate policy). Tests: 15 passed. Co-Authored-By: Sol via Codex <noreply@openai.com> |
||
| src/kreeader_tts_sdk | ||
| tests | ||
| .gitignore | ||
| CLAUDE.md | ||
| plugin.toml | ||
| pyproject.toml | ||
| README.md | ||
kreeader TTS SDK
kreeader-tts-sdk implements the shared HTTP, manifest, settings, and frozen-voice contract for out-of-process kreeader-studio TTS plugins. Engine repositories only provide an EngineAdapter; this package never imports an engine or PyTorch.
Adapter contract
Version 0.3.0 is a breaking adapter/HTTP contract revision. Migrating from
0.2.x: return (wav_bytes, metadata) from design and clone, accept a
FrozenVoice in speak, and send both affirmative consent and a non-empty
rights field when cloning.
An adapter supplies capabilities() and settings_schema(), creates frozen WAV voices with design() and/or clone(), renders them with speak(), and reports health(). Unsupported voice sources raise NotSupported. All audio crossing this interface is a complete WAV byte string.
from kreeader_tts_sdk import EngineAdapter, FrozenVoice, NotSupported, create_app
class MyEngine(EngineAdapter):
def capabilities(self): return {"voice_sources": ["sample"], "languages": ["en"], "emotion": "none", "speed_control": False, "streaming": False, "watermark": None, "hardware": {"cpu_ok": True}, "engine": {"name": "mine", "version": "1"}}
def settings_schema(self): return {"properties": {}, "defaults": {}}
def design(self, description, seed, lang, settings): raise NotSupported("sample only")
def clone(self, reference_wav, transcript, settings):
wav = my_engine.clone(reference_wav, transcript)
return wav, {"engine_voice_id": my_engine.voice_id(wav)}
def speak(self, voice: FrozenVoice, text, emotion, cues, rate, settings):
return my_engine.speak(voice.wav, text, rate=rate)
def health(self): return {"status": "ok", "engine": {"name": "mine", "version": "1"}}
app = create_app(MyEngine(), "plugin.toml", "./plugin-data")
The adapter runs behind FastAPI in its own Python process. Its plugin.toml holds stable plugin metadata—ID, display name, license, and artifact—while live adapter capabilities and PLUGIN_VERSION form the runtime manifest.
Mock server
From a source checkout:
PYTHONPATH=src python -m kreeader_tts_sdk.dev --adapter mock --port 8080
The mock supports both voice sources and generates deterministic PCM16 tones. It requires no model files and is useful in CI. Its temporary voice store can be made persistent with --data-dir PATH.
Endpoints
GET /studio/healthGET /studio/manifestGET,PUT /studio/settingsGET /studio/voicesPOST /studio/voices/designPOST /studio/voices/cloneDELETE /studio/voices/{voice_ref}POST /studio/speakPOST /v1/audio/speech
Clone requests are multipart uploads and require an explicitly true consent
field plus a non-empty license or source_rights field. Every frozen voice is
stored as voices/<voice_ref>/voice.wav beside meta.json, including its
SHA-256, source, provenance, creation time, and clone consent/license where
applicable.