# Chatterbox TTS candidate-provider workflow

Use this when evaluating the local Chatterbox HTTP TTS server for AutoShortsBot / TrueTraceShorts voiceovers.

## Scope

Chatterbox is a **candidate provider** until the user explicitly promotes it. Do not switch the production default, regenerate captions, render videos, or upload platform assets during a voice test.

## Current endpoint shape

Base URL over Tailscale:

```text
http://100.101.173.25:8004
```

Endpoints:

- Health/UI initial data: `/api/ui/initial-data`
- Voices: `/v1/audio/voices`
- OpenAI-compatible speech: `/v1/audio/speech`
- Custom Chatterbox endpoint: `/tts`
- OpenAPI docs: `/openapi.json`

## Connectivity test

Run only Chatterbox checks when the user asks for a Chatterbox-only test. Do **not** compare Edge/Kokoro/other TTS systems in that step.

Required checks:

1. `curl -s -o <file> -w '%{http_code}' http://100.101.173.25:8004/api/ui/initial-data`
2. `curl -s -o <file> -w '%{http_code}' http://100.101.173.25:8004/v1/audio/voices`
3. Report reachability, HTTP status, whether config/model info is visible, available voices, selected voice.

## TTS test artifact contract

For a one-shot TTS probe, save:

```text
data/audio/chatterbox_tests/<name>.wav
data/audio/chatterbox_tests/<name>.metadata.json
```

Metadata fields:

```json
{
  "provider": "chatterbox_http",
  "base_url": "http://100.101.173.25:8004",
  "speech_endpoint": "http://100.101.173.25:8004/v1/audio/speech",
  "voices_endpoint": "http://100.101.173.25:8004/v1/audio/voices",
  "model": "tts-1",
  "voice": "Emily.wav",
  "text_sha256": "...",
  "output_path": "...",
  "output_sha256": "...",
  "duration": 0.0,
  "file_size": 0,
  "request_time": "...",
  "success": true,
  "error": null
}
```

Try `model: tts-1` first with `response_format: wav`; only fallback to `chatterbox-turbo` if `tts-1` fails.

## Endpoints and controllable parameters

### `/v1/audio/speech`

OpenAI-compatible request fields:

```json
{
  "model": "tts-1",
  "input": "Text",
  "voice": "Emily.wav",
  "response_format": "wav",
  "speed": 1.0,
  "seed": 1234,
  "language": "en"
}
```

### `/tts`

Custom request fields:

```json
{
  "text": "Text",
  "voice_mode": "predefined",
  "predefined_voice_id": "Emily.wav",
  "output_format": "wav",
  "split_text": true,
  "chunk_size": 180,
  "temperature": 0.65,
  "exaggeration": 0.45,
  "cfg_weight": 0.6,
  "seed": 4101,
  "speed_factor": 1.03,
  "language": "en",
  "stream": false
}
```

Chatterbox does **not** expose direct sliders for gender, age, accent, trust, energy, or drama. Those are controlled indirectly via voice file plus generation params.

## Voice-profile target for Scam Red Flags

User target profile:

- Female / neutral-female
- Age impression 30–45
- Calm but not slow
- Friendly, clear, attentive
- Serious, not panicked
- Clear international English
- Energy 6/10
- Drama 2/10
- Trust 9/10

Candidate voices to test first:

- `Emily.wav`
- `Elena.wav`
- `Olivia.wav`
- `Taylor.wav`
- `Gianna.wav`

## Telegram voice proposal workflow

When the user asks for voice proposals, generate a small set and send them as native Telegram voice notes using media-cache `.ogg` files:

1. Generate WAV from Chatterbox.
2. Convert to Opus/Ogg for Telegram voice delivery:

```bash
ffmpeg -y -i input.wav -vn -c:a libopus -b:a 96k -ar 48000 -application voip output.ogg
```

3. Put `.ogg` files under `~/.hermes/media_cache/...` and deliver with `MEDIA:/absolute/path.ogg`.
4. Include short labels, voice ID, duration, and SHA256.

If the user says the voice notes sound **blechern** / metallic, do not keep tuning exotic parameters. First retry with standard voices and standard presets:

- Use `/v1/audio/speech`, not `/tts`.
- Send only `model`, `input`, `voice`, and `response_format`.
- Avoid custom `temperature`, `exaggeration`, `cfg_weight`, and speed overrides.
- Use higher Opus bitrate (`96k`) for Telegram voice export.
- If still metallic, send WAV files too to separate Chatterbox output quality from Telegram transcoding/playback.

## Production voice consistency / fallback rule

When a video has already been established as a Chatterbox/Taylor production standard and Chatterbox temporarily refuses connections, do **not** silently ship an alternate voice as the normal review candidate. The safe pattern is:

1. Run the Chatterbox connectivity checks (`/api/ui/initial-data`, `/v1/audio/voices`) and one short Taylor `/v1/audio/speech` probe.
2. If Chatterbox is still down, clearly label any alternate-provider render as a **temporary fallback / not voice-standard**, and keep the approval package voice/version/hash tied to that actual fallback.
3. Before final delivery or upload approval, retry Chatterbox once if the user expects Taylor consistency or questions the voice.
4. If Chatterbox is reachable again, re-render the same candidate with Chatterbox Taylor, regenerate forced alignment/captions, rebuild package hashes, and deliver a new approval command. Never reuse the fallback approval command.

## Hard non-goals during tests

Unless the user explicitly expands scope:

- no other TTS provider comparison;
- no video render;
- no caption regeneration;
- no upload;
- no default-provider switch.
