Expand description
Resident engine: a per-user background process that keeps the loaded model in memory
so consecutive ftts say invocations skip the multi-second model load.
Shape: ftts say connects to a loopback TCP daemon (spawned on demand from the same
binary) and sends one synthesis request; the daemon holds the hydrated LoadedModel
and TtsEngine between requests and exits by itself after a
configurable idle period (default ten minutes). Everything else — argument handling,
voice resolution, robot events, output writing — stays in the client process, so the
observable contract of ftts say is unchanged.
Loopback TCP is the one transport that behaves identically on Linux, macOS, and
Windows with only the standard library. Access control is the state file, not the
port: the daemon binds an ephemeral 127.0.0.1 port and writes {port, token, …} to a
file only the invoking user can read (0600 on Unix; the per-user profile directory’s
ACL on Windows), and every request must present that token. Texts are sensitive, so
the daemon holds no history: requests are served from memory and dropped.
Failure philosophy: the resident path may only ever make say faster, never break
it. Every transport-level problem (no daemon, stale state file, version or artifact
mismatch, malformed reply) falls back to the classic in-process load. Only a genuine
synthesis error crosses the wire as an error, carrying its exit-code class.
Structs§
- Wire
Request - One synthesis request as it crosses the wire. Everything the daemon needs to rebuild
the exact
SynthesisRequestthe client would have run inline.
Functions§
- enabled
- Whether the resident path is enabled at all: on by default, disabled by the
sayflag or byFTTS_NO_RESIDENT=1for scripts that cannot pass flags. - run_
daemon - Run the resident daemon until the idle period passes without a request.
- try_
synthesize - Try to synthesize through a resident daemon, spawning one if none is listening.