What changed
translate-text now follows the same bounded provider path as the translate
route. It tries the fast translation model first, then falls back when needed.
It also accepts a JSON reply wrapped in a code fence, which some providers send
despite JSON-mode requests.
If both providers are unavailable, the route returns a dependency failure instead of presenting it as an internal server error. That makes a paid failure clearer to callers and keeps retry decisions honest.
What stays the same
The request and response fields are unchanged: send text and
target_language, then receive translated_text and the detected source
language. Markdown, code blocks, URLs, and proper nouns remain part of the
translation contract.