























@@ -493,6 +493,110 @@ transcoded to raw 16 kHz mono PCM with `ffmpeg`. The legacy provider alias
493493}
494494```
495495496+### TTS personas
497+498+Use `messages.tts.personas` when you want a stable spoken identity that can be
499+applied deterministically across providers. A persona can prefer one provider,
500+define provider-neutral prompt intent, and carry provider-specific bindings for
501+voices, models, prompt templates, seeds, and voice settings.
502+503+```json5
504+{
505+ messages: {
506+ tts: {
507+ auto: "always",
508+ persona: "alfred",
509+ personas: {
510+ alfred: {
511+ label: "Alfred",
512+ description: "Dry, warm British butler narrator.",
513+ provider: "google",
514+ fallbackPolicy: "preserve-persona",
515+ prompt: {
516+ profile: "A brilliant British butler. Dry, witty, warm, charming, emotionally expressive, never generic.",
517+ scene: "A quiet late-night study. Close-mic narration for a trusted operator.",
518+ sampleContext: "The speaker is answering a private technical request with concise confidence and dry warmth.",
519+ style: "Refined, understated, lightly amused.",
520+ accent: "British English.",
521+ pacing: "Measured, with short dramatic pauses.",
522+ constraints: ["Do not read configuration values aloud.", "Do not explain the persona."],
523+ },
524+ providers: {
525+ google: {
526+ model: "gemini-3.1-flash-tts-preview",
527+ voiceName: "Algieba",
528+ promptTemplate: "audio-profile-v1",
529+ },
530+ openai: {
531+ model: "gpt-4o-mini-tts",
532+ voice: "cedar",
533+ },
534+ elevenlabs: {
535+ voiceId: "voice_id",
536+ modelId: "eleven_multilingual_v2",
537+ seed: 42,
538+ voiceSettings: {
539+ stability: 0.65,
540+ similarityBoost: 0.8,
541+ style: 0.25,
542+ useSpeakerBoost: true,
543+ speed: 0.95,
544+ },
545+ },
546+ },
547+ },
548+ },
549+ },
550+ },
551+}
552+```
553+554+Resolution is deterministic:
555+556+1. `/tts persona <id>` local preference, if set.
557+2. `messages.tts.persona`, if set.
558+3. No persona.
559+560+Provider selection is explicit-first:
561+562+1. Direct provider overrides from CLI, gateway, Talk, or allowed TTS directives.
563+2. `/tts provider <id>` local preference.
564+3. Active persona `provider`.
565+4. `messages.tts.provider`.
566+5. Registry auto-select.
567+568+For each provider attempt, OpenClaw merges:
569+570+1. `messages.tts.providers.<id>`
571+2. `messages.tts.personas.<persona>.providers.<id>`
572+3. trusted request overrides
573+4. allowed model-emitted TTS directive overrides
574+575+`fallbackPolicy` controls what happens when an active persona has no binding for
576+an attempted provider:
577+578+- `preserve-persona` keeps provider-neutral persona prompt fields available to
579+ providers. This is the default.
580+- `provider-defaults` omits the persona from provider prompt preparation for
581+ that attempt, so the provider uses its neutral defaults while still allowing
582+ fallback to continue.
583+- `fail` skips that provider attempt with `reasonCode: "not_configured"` and
584+`personaBinding: "missing"`. Fallback providers are still tried; the whole TTS
585+ request fails only if every attempted provider is skipped or fails.
586+587+Persona prompt fields are provider-neutral. Providers decide how to use them.
588+Google wraps them only when the effective Google provider config sets
589+`promptTemplate: "audio-profile-v1"` or `personaPrompt`; its older
590+`audioProfile` and `speakerName` fields are still prepended as Google-specific
591+prompt text. OpenAI maps prompt fields to `instructions` when no explicit
592+OpenAI `instructions` value is configured. Providers without prompt-like
593+controls use the provider-specific persona bindings only.
594+595+Gemini inline audio tags are transcript content, not persona config. If the
596+assistant or an explicit `[[tts:text]]` block includes tags such as `[whispers]`
597+or `[laughs]`, OpenClaw preserves them inside the Gemini transcript. OpenClaw
598+does not generate configured start tags.
599+496600### Disable Microsoft speech
497601498602```json5
@@ -565,6 +669,12 @@ Then run:
565669- If `provider` is **unset**, OpenClaw uses the first configured speech provider in registry auto-select order.
566670- Legacy `provider: "edge"` config is repaired by `openclaw doctor --fix` and
567671 rewritten to `provider: "microsoft"`.
672+- `persona`: default TTS persona id from `personas`.
673+- `personas.<id>`: stable spoken identity. The id is normalized to lowercase.
674+- `personas.<id>.provider`: preferred speech provider for the persona. Explicit provider overrides and local provider prefs still win.
675+- `personas.<id>.fallbackPolicy`: `preserve-persona` (default), `provider-defaults`, or `fail`; see [TTS personas](#tts-personas).
676+- `personas.<id>.prompt`: provider-neutral persona prompt fields (`profile`, `scene`, `sampleContext`, `style`, `accent`, `pacing`, `constraints`).
677+- `personas.<id>.providers.<provider>`: provider-specific persona binding merged over `providers.<provider>`.
568678- `summaryModel`: optional cheap model for auto-summary; defaults to `agents.defaults.model.primary`.
569679- Accepts `provider/model` or a configured model alias.
570680- `modelOverrides`: allow the model to emit TTS directives (on by default).
@@ -621,6 +731,8 @@ Then run:
621731- `providers.google.voiceName`: Gemini prebuilt voice name (default `Kore`; `voice` is also accepted).
622732- `providers.google.audioProfile`: natural-language style prompt prepended before the spoken text.
623733- `providers.google.speakerName`: optional speaker label prepended before the spoken text when your TTS prompt uses a named speaker.
734+- `providers.google.promptTemplate`: set to `audio-profile-v1` to wrap active persona prompt fields in a deterministic Gemini TTS prompt structure.
735+- `providers.google.personaPrompt`: Google-specific extra persona prompt text appended to the template's Director's Notes.
624736- `providers.google.baseUrl`: override the Gemini API base URL. Only `https://generativelanguage.googleapis.com` is accepted.
625737- If `messages.tts.providers.google.apiKey` is omitted, TTS can reuse `models.providers.google.apiKey` before env fallback.
626738- `providers.gradium.baseUrl`: override Gradium API base URL (default `https://api.gradium.ai`).
@@ -750,8 +862,9 @@ Slash commands write local overrides to `prefsPath` (default:
750862751863Stored fields:
752864753-- `enabled`
865+- `auto`
754866- `provider`
867+- `persona`
755868- `maxLength` (summary threshold; default 1500 chars)
756869- `summarize` (default `true`)
757870@@ -837,6 +950,7 @@ Discord note: `/tts` is a built-in Discord command, so OpenClaw registers
837950/tts chat default
838951/tts latest
839952/tts provider openai
953+/tts persona alfred
840954/tts limit 2000
841955/tts summary off
842956/tts audio Hello from OpenClaw
@@ -850,6 +964,7 @@ Notes:
850964- `/tts on` writes the local TTS preference to `always`; `/tts off` writes it to `off`.
851965- `/tts chat on|off|default` writes a session-scoped auto-TTS override for the current chat.
852966- Use config when you want `inbound` or `tagged` defaults.
967+- `/tts persona <id>` writes the local persona preference; `/tts persona off` clears it.
853968- `limit` and `summary` are stored in local prefs, not the main config.
854969- `/tts audio` generates a one-off audio reply (does not toggle TTS on).
855970- `/tts latest` reads 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.
@@ -883,6 +998,7 @@ Gateway methods:
883998- `tts.disable`
884999- `tts.convert`
8851000- `tts.setProvider`
1001+- `tts.setPersona`
8861002- `tts.providers`
88710038881004## Related
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。