Model-driven directives

By default, the assistant can emit [[tts:...]] directives to override voice, model, or speed for a single reply, plus an optional [[tts:text]]...[[/tts:text]] block for expressive cues that should appear in audio only:

Here you go.

[[tts:speakerVoiceId=pMsXgVXv3BLzUgSXRplE model=eleven_v3 speed=1.1]]
[[tts:text]](laughs) Read the song once more.[[/tts:text]]

When tts.auto is "tagged", directives are required to trigger audio. Streaming block delivery strips directives from visible text before the channel sees them, even when split across adjacent blocks.

A reply can consist entirely of a nonempty [[tts:text]]...[[/tts:text]] block. No visible text prefix is required, including when the model also returns reasoning.

provider=... is ignored unless modelOverrides.allowProvider: true. When a reply declares provider=..., the other keys in that directive are parsed only by that provider; unsupported keys are stripped and reported as TTS directive warnings.

Available directive keys:

Disable model overrides entirely:

{ tts: { modelOverrides: { enabled: false } } }

Allow provider switching while keeping other knobs configurable:

{ tts: { modelOverrides: { enabled: true, allowProvider: true, allowSeed: false } } }

Slash commands

Single command /tts. On Discord, Apus also registers /voice because /tts is a built-in Discord command — text /tts ... still works.

/tts off | on | status
/tts chat on | off | default
/tts latest
/tts provider <id>
/tts persona <id> | off
/tts limit <chars>
/tts summary off
/tts audio <text>

Commands require an authorized sender (allowlist/owner rules apply) and either commands.text or native command registration must be enabled.

Behavior notes:

Per-user preferences

Slash commands write local overrides to the TTS preferences path. The default is ~/.apus/settings/tts.json; override it with APUS_TTS_PREFS. Doctor moves the retired global tts.prefsPath value into shared machine state. Advanced multi-agent setups may still set agents.entries.<id>.tts.prefsPath when agents intentionally use separate preference stores.

Stored field Effect
auto Local auto-TTS override (always, off, …)
provider Local primary provider override
persona Local persona override
maxLength Summary/truncation threshold (default 1500 chars, /tts limit range 100–4096)
summarize Summary toggle (default true)

These override the effective config from tts plus the active agents.entries.*.tts block for that host.