On this page
On this page
Tools
Text-to-speech commands and directives
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:
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:
provider(registered provider id; requiresallowProvider: true)speakerVoice/speakerVoiceId(legacy aliases:voice,voiceName,voice_name,google_voice,voiceId)model/google_modelstability,similarityBoost,style,speed,useSpeakerBoostvol/volume(MiniMax volume,(0, 10])pitch(MiniMax integer pitch, −12 to 12; fractional values are truncated)emotion(Volcengine emotion tag)applyTextNormalization(auto|on|off)languageCode(ISO 639-1)seed
Disable model overrides entirely:
Allow provider switching while keeping other knobs configurable:
Slash commands
Single command /tts. On Discord, OpenClaw also registers /voice because
/tts is a built-in Discord command — text /tts ... still works.
Behavior notes:
/tts onwrites the local TTS preference toalways;/tts offwrites it tooff./tts chat on|off|defaultwrites a session-scoped auto-TTS override for the current chat./tts persona <id>writes the local persona preference;/tts persona offclears it./tts latestreads the latest assistant reply from the current session transcript and sends it as audio once. It stores only a hash of that reply on the session entry to suppress duplicate voice sends./tts audiogenerates a one-off audio reply (does not toggle TTS on)./tts limit <chars>accepts 100–4096 (4096 is the Telegram caption/message max); values outside that range are rejected.limitandsummaryare stored in local prefs, not the main config./tts statusincludes fallback diagnostics for the latest attempt —Fallback: <primary> -> <used>,Attempts: ..., and per-attempt detail (provider:outcome(reasonCode) latency)./statusshows the active TTS mode plus configured provider, model, voice, and sanitized custom endpoint metadata when TTS is enabled.
Per-user preferences
Slash commands write local overrides to the TTS preferences path. The default is
~/.openclaw/settings/tts.json; override it with OPENCLAW_TTS_PREFS. Doctor
moves the retired global tts.prefsPath value into shared machine state.
Preference updates finish durable persistence before reporting success, while the
Gateway remains responsive during disk flushes. Concurrent updates retain their
order and preserve unrelated preferences.
Legacy synchronous SDK setters use the same queue and wait for earlier updates.
Advanced multi-agent setups may still set agents.entries.<id>.tts.prefsPath
when agents intentionally use separate preference stores.
Missing preference files use configured defaults. If a file cannot be read or contains malformed JSON, read-only operations warn and use those defaults. Preference-changing commands refuse until you repair the file or its permissions, so they do not overwrite unread settings.
| 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.