/** * Speech API client * Handles text-to-speech synthesis and voice listing via /api/speech */ import { apiGet } from "./client"; import { API_BASE_URL } from "../config"; export type SpeechTier = "default" | "premium" | "fallback"; export interface VoiceInfo { id: string; name: string; language: string; gender?: string; preview_url?: string; tier?: SpeechTier; isDefault?: boolean; } export interface SynthesizeOptions { text: string; voice?: string; speed?: number; format?: string; tier?: string; } export interface VoicesResponse { data: VoiceInfo[]; } export interface ProviderHealth { available: boolean; } export interface HealthResponse { data: { stt: ProviderHealth; tts: ProviderHealth; }; } /** * Fetch available TTS voices * Optionally filter by tier (default, premium, fallback) */ export async function getVoices(tier?: SpeechTier): Promise { const endpoint = tier ? `/api/speech/voices?tier=${tier}` : "/api/speech/voices"; return apiGet(endpoint); } /** * Fetch health status of speech providers (STT and TTS) */ export async function getHealthStatus(): Promise { return apiGet("/api/speech/health"); } /** * Synthesize text to speech audio * Returns the audio as a Blob since the API returns binary audio data */ export async function synthesizeSpeech(options: SynthesizeOptions): Promise { const url = `${API_BASE_URL}/api/speech/synthesize`; const response = await fetch(url, { method: "POST", headers: { "Content-Type": "application/json", }, credentials: "include", body: JSON.stringify(options), }); if (!response.ok) { const errorText = await response.text().catch(() => "Unknown error"); throw new Error(`Speech synthesis failed: ${errorText}`); } return response.blob(); }