Inworld
Inworld (API docs; subscribe through that link for $10 in credits) is the default voice provider for the voice clone (rule 143). Instant voice cloning is free on every plan, and the free plan includes about 70 minutes of speech.
The two calls
The client (src/extensions/inworld/client.ts) knows only these, each with Authorization: Basic <INWORLD_API_KEY> (the Base64 credentials from the Inworld portal, sent as they are):
POST https://api.inworld.ai/voices/v1/voices:clone, JSONdisplayName,languageCode(LOG_VOICE_LANGUAGE, defaulten-IE; when Inworld answers 400INVALID_ARGUMENTit is sent again asen-GB, Inworld's own example of a British accent),descriptionnaming the accent (LOG_VOICE_ACCENT, default Irish), andvoiceSamples, eachaudioDataas base64 wav with itstranscriptionwhen~/.logCli/transcriptsholds matt's AssemblyAI transcript of that file (Inworld says TTS-2 cloning makes its own and ignores it, so a missing one is not paid for).log clone voice --apply --replacemakes it again, keeping the old voice id underprevious(rule 145). Inworld works best with 10 to 30 s and cuts longer clips at 30 s, so log sends matt's own voice notes shortest first up to 30 s in all. The answer'svoice.voiceId({workspace}__{voice}) is kept in~/.logCli/voice/clone.jsonunderinworld.POST https://api.inworld.ai/tts/v1/voice, JSONtext(up to 2,000 characters; log keeps a voice note under 600),voiceId,modelId,language(the language the clone was made in) andaudioConfig(audioEncodingWAV,speakingRatefromLOG_VOICE_SPEED, default 1.15). The answer'saudioContentis base64 audio. No accent instruction is sent: the clone carries the accent (rule 147). Oninworld-tts-2the text gets[breathe]at the start and once at least 8 words have gone by (withBreaths); emotion tags such as[excited]pass through as written.inworld-tts-2-flashignores tags, so it gets none.
A clone made on Inworld speaks with inworld-tts-2 (its preferred model, rule 146) unless --model says otherwise.
Inworld's own docs say instant cloning may not do well on unique accents and gets closer the nearer the sample is to 30 s, so matt's clone is one continuous 30 s of his own Discord voice note rather than several short ones (rule 147).
Setting it up
INWORLD_API_KEYin.env.local; its name is in.env.example.log clone voice, read the list, thenlog clone voice --applyonce, andlog clone speak --text "…"to hear it.