{"id":48206,"plugin_id":"plugins_6abe6d86380c819184783cc2602647be","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-24T13:35:42.572Z","digest":"5f54bbdaea82044e9e83f91ff7bf61bc392726a224da88f3ad26390177890a25","against":null,"payload":{"description":"Add offline, on-device text to speech to a software project with loudkit, an open-source engine with open weights, in Python, JavaScript or TypeScript (Node), Rust, Go or Swift (macOS, iOS). Use when the user wants speech output in their app without a cloud TTS API, needs local or private speech synthesis, or asks how to integrate loudkit.","included_files":[{"relative_path":"references/go.md","size_in_bytes":6167},{"relative_path":"references/js.md","size_in_bytes":5560},{"relative_path":"references/python.md","size_in_bytes":6359},{"relative_path":"references/rust.md","size_in_bytes":6239},{"relative_path":"references/swift.md","size_in_bytes":6849}],"name":"add-offline-tts","skill_md_contents":"---\nname: add-offline-tts\ndescription: Add offline, on-device text to speech to a software project with loudkit, an open-source engine with open weights, in Python, JavaScript or TypeScript (Node), Rust, Go or Swift (macOS, iOS). Use when the user wants speech output in their app without a cloud TTS API, needs local or private speech synthesis, or asks how to integrate loudkit.\n---\n\n# Add offline text to speech to a project\n\nloudkit runs the same engine in five languages. Audio is made on the device\nthat runs the code. There is no API key, no account and no per-request cost.\nThe code is Apache-2.0; the voice licences are in the `choose-voice` skill.\n\n## Steps\n\n1. **Find the target.** Read the project to find its language and platform:\n\n   | Project file | Port | Reference |\n   |---|---|---|\n   | `pyproject.toml`, `requirements.txt` | Python | [references/python.md](references/python.md) |\n   | `package.json` (Node 20+) | JavaScript / TypeScript | [references/js.md](references/js.md) |\n   | `Cargo.toml` | Rust | [references/rust.md](references/rust.md) |\n   | `go.mod` | Go | [references/go.md](references/go.md) |\n   | `Package.swift`, `.xcodeproj` (macOS 14+, iOS 17+) | Swift | [references/swift.md](references/swift.md) |\n\n   Read only the reference for that port. If you cannot tell, ask.\n\n2. **Say what does not fit.** There is no port for Android or for the browser\n   (WebAssembly). The JavaScript port is for Node, not the browser.\n   Say so instead of forcing a port onto a platform it does not support.\n   For a desktop program in another language (C#, Java), `loudkit serve` runs\n   a local HTTP server on the same machine that the program can call; see https://github.com/loudreader/loudkit/blob/main/docs/guides/04-server-and-agents.md\n\n3. **Pick a model.** Start with `loudreader/loudr-1` (reference quality).\n   Offer `loudreader/loudr-1-turbo` when latency matters more. Switching is a\n   change of name; the code and voices stay the same. Tell the user to compare\n   both on their own text.\n\n4. **State the download.** The first load fetches the model once, then runs\n   offline:\n\n   | Runtime | loudr-1 | loudr-1-turbo |\n   |---|---:|---:|\n   | Python, PyTorch | 0.75 GB | 0.72 GB |\n   | ONNX (JS, Rust, Go, Python without torch) | 2.60 GB | 2.44 GB |\n   | CoreML (Swift) | 2.46 GB | 2.44 GB |\n\n   For a mobile or desktop app, download at first launch or on demand, not\n   inside the app bundle, unless the user decides otherwise.\n\n5. **Write the integration.** Follow the reference for the port:\n   - Load the engine once and keep it. Loading takes seconds.\n   - Use `stream` when playback should start before the whole passage is\n     rendered, and `synthesize` for a file.\n   - Pin the release revision (`v0.1.1`) for reproducible builds.\n   - Do not invent API names. Use only the calls in the reference. If the user\n     needs something the reference does not show, link the full guide.\n\n6. **Test it.** Add a test that synthesises one short sentence and checks that\n   the audio is not empty. Ask before running it: it downloads the model.\n   In a cloud environment, run it only if it can reach the internet, and say\n   it ran there. Without a shell, give the command to run.\n\n## Rules\n\n- WAVs saved from Python carry a provenance note that marks them as\n  synthetic; keep it unless the user asks otherwise. The Go, Rust, JS and\n  Swift ports write plain PCM with no note: tell the user to label the audio\n  as synthetic in their app or its metadata.\n- The project measured speed on specific hardware only. Do not promise a speed\n  on the user's device; tell them to measure it.\n- For a custom voice, use the `clone-voice` skill.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}