/** * Alibaba DashScope TTS provider (qwen-tts model). * * Implements the SpeechProviderPlugin contract directly because DashScope's * response shape (output.audio.url for the audio binary, no direct stream) * doesn't fit the OpenAI-compatible factory. * * Implementation notes (per docs/voice-rearchitecture.md ยง8.4.1): * - `synthesizeStream` is intentionally not implemented. Native qwen-tts * streaming uses a WebSocket protocol * (wss://dashscope.aliyuncs.com/api-ws/v1/inference); speak-core's stream * fallback wraps `synthesize` output as a single-chunk ReadableStream so * callers see the same shape. * - `maxTextLength = 512` (DashScope qwen-tts hard limit). Enforced upstream * via `truncateAtSentenceBoundary` before this provider sees the text. * - The audio URL returned by DashScope is hosted on Alibaba's CDN (variable * hostname). We do not SSRF-guard the audio fetch because: * (a) the URL is provided by the same provider we already trust for the * initial synthesis call, * (b) it's HTTPS-only and short-lived (~5 min TTL), * (c) maintaining a hostname allowlist breaks every time Alibaba rotates * CDN domains. * A dedicated `assertSafeUrl` for trusted-CDN responses can be added later * as a hardening pass. */ import type { SpeechProviderPlugin } from '../speech-provider-types.js'; export declare const alibabaSpeechProvider: SpeechProviderPlugin;