Gemini TTS audio now leaves the router as it arrives

Gemini answers in server-sent events with base64 audio per frame, and the router was decoding the whole body before sending any of it. On a streaming route each frame is now decoded and forwarded as it arrives, which moved first-byte latency from 3695 ms to 786 ms on the same request, and gives the Dominican Spanish accent a streaming voice for the first time.

The router already asked Gemini for its streaming endpoint with server-sent events. The response was then collected in full so the base64 audio inside each frame could be decoded, which meant the caller waited for the entire synthesis. Frames are now decoded one at a time.

Measured on the same request with the provider pinned: the buffered route returned one chunk after 3695 ms, and the streaming route returned 159 chunks with the first at 786 ms.

es-DO is served only by Gemini, so it previously had no voice at all on a streaming route. Measured unpinned on es-DO: 153 chunks, first at 1321 ms.

Above 700 characters Gemini is asked for a single response rather than a stream, because its streaming response truncates on long audio. A streaming request that can only reach Gemini with more text than that is now refused with 503 no_streaming_tts_provider instead of being answered with a body that arrives all at once. The buffered route serves it.

A frame split across two network reads is held until it is complete, so audio is never truncated by a partial base64 value. The whole-body decoder is now the incremental decoder driven to completion, so the two cannot disagree about what a response means.

Action: No migration is required.