UNPKG

voiceai-sdk

Version:

Official SDK for SLNG.AI Voice API - Text-to-Speech, Speech-to-Text, and LLM services

1 lines 64 kB
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/utils/catalog.ts","../src/index.ts","../src/client.ts","../src/tts.ts","../src/providers/index.ts","../src/providers/tts.ts","../src/utils/request.ts","../src/providers/stt.ts","../src/providers/llm.ts","../src/stt.ts","../src/llm.ts","../src/auth.ts","../src/warmup.ts","../src/types.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { makeRequest } from './request';\n\nexport interface ModelCatalog {\n tts: Record<string, {\n name: string;\n description: string;\n voices?: string[];\n languages?: string[];\n pricing: string;\n }>;\n stt: Record<string, {\n name: string;\n description: string;\n languages?: string[];\n pricing: string;\n }>;\n llm: Record<string, {\n name: string;\n description: string;\n pricing: string;\n }>;\n lastUpdated: string;\n}\n\nclass CatalogManager {\n private catalog: ModelCatalog | null = null;\n private lastFetch: number = 0;\n private cacheTimeout = 24 * 60 * 60 * 1000; // 24 hours cache in memory\n\n private async fetchCatalog(): Promise<ModelCatalog> {\n try {\n // Semi-private endpoint - not documented but accessible\n // Obfuscate the endpoint slightly\n const endpoint = Buffer.from('L2FscGhhL2NhdGFsb2c=', 'base64').toString();\n \n const response = await fetch(`https://api.slng.ai${endpoint}`, {\n headers: {\n 'X-SDK-Version': '1.0.0',\n 'X-SDK-Client': 'voiceai-sdk',\n }\n });\n\n if (!response.ok) {\n throw new Error('Failed to fetch catalog');\n }\n\n return await response.json();\n } catch (error) {\n // Fallback to embedded defaults if endpoint unavailable\n return this.getDefaultCatalog();\n }\n }\n\n private getDefaultCatalog(): ModelCatalog {\n return {\n tts: {\n 'orpheus': {\n name: 'Orpheus',\n description: 'Frontier TTS model with emotive speech',\n voices: ['tara', 'leah', 'jess', 'leo', 'dan', 'mia', 'zac', 'zoe'],\n languages: ['en', 'fr', 'de', 'ko', 'zh', 'es', 'it', 'hi'],\n pricing: '$0.30 per 1M characters'\n },\n 'orpheus-indic': {\n name: 'Orpheus Indic',\n description: 'Optimized for 8 major Indian languages, hosted in Mumbai',\n voices: ['hindi_male', 'hindi_female', 'tamil_male', 'tamil_female', 'telugu_male', 'bengali_female', 'marathi_male', 'gujarati_female', 'kannada_male', 'malayalam_female'],\n languages: ['hi', 'ta', 'te', 'bn', 'mr', 'gu', 'kn', 'ml'],\n pricing: '$0.04 per minute generated'\n },\n 'elevenlabs/multi-v2': {\n name: 'ElevenLabs Multi-v2',\n description: 'Multilingual model supporting 29+ languages',\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul', 'Domi', 'Dave', 'Fin', 'Bella'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'hi', 'ar', 'zh', 'ja', 'ko'],\n pricing: '$0.30 per 1M characters'\n },\n 'elevenlabs/turbo-v2-5': {\n name: 'ElevenLabs Turbo v2.5',\n description: 'Ultra-fast TTS with low latency',\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt'],\n pricing: '$0.25 per 1M characters'\n },\n 'elevenlabs/v3': {\n name: 'ElevenLabs v3',\n description: 'Latest generation with high-quality voices',\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul', 'Domi', 'Dave', 'Fin', 'Bella'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'hi'],\n pricing: '$0.35 per 1M characters'\n },\n 'elevenlabs/flash-v2-5': {\n name: 'ElevenLabs Flash v2.5',\n description: 'Fast model with good quality balance',\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl'],\n pricing: '$0.20 per 1M characters'\n },\n 'koroko': {\n name: 'Koroko',\n description: 'Efficient 82M parameter model',\n languages: ['en'],\n pricing: '$0.15 per 1M characters'\n },\n 'vui': {\n name: 'VUI',\n description: 'Fast, reliable baseline model',\n voices: ['default'],\n languages: ['en'],\n pricing: '$0.10 per 1M characters'\n },\n 'xtts-v2': {\n name: 'XTTS-v2',\n description: 'Voice cloning in 17 languages',\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'tr', 'ru', 'nl', 'cs', 'ar', 'zh', 'ja', 'ko', 'hu', 'hi'],\n pricing: '$0.50 per 1M characters'\n },\n 'mars6': {\n name: 'MARS6',\n description: 'Voice + prosody cloning',\n languages: ['en-us', 'fr-fr', 'de-de', 'es-es', 'it-it', 'pt-pt', 'zh-cn', 'ja-jp', 'ko-kr', 'nl-nl'],\n pricing: '$0.60 per 1M characters'\n },\n 'twi-speecht5': {\n name: 'Twi SpeechT5',\n description: 'Specialized for Twi language',\n languages: ['tw'],\n pricing: '$0.25 per 1M characters'\n }\n },\n stt: {\n 'whisper-v3': {\n name: 'Whisper-v3',\n description: 'OpenAI\\'s best speech recognition',\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'ru', 'zh', 'ja', 'ko', 'ar', 'hi'],\n pricing: '$0.006 per minute'\n },\n 'kyutai': {\n name: 'Kyutai Streaming',\n description: 'High-performance streaming STT for French/English, hosted in Mumbai',\n languages: ['en', 'fr'],\n pricing: '4 credits per minute'\n }\n },\n llm: {\n 'llama-4-scout': {\n name: 'Llama 4 Scout',\n description: 'Fast, capable 17B parameter model',\n pricing: '$0.10 per 1M tokens'\n }\n },\n lastUpdated: new Date().toISOString()\n };\n }\n\n async getCatalog(): Promise<ModelCatalog> {\n // Use in-memory cache for 24 hours\n const now = Date.now();\n if (this.catalog && (now - this.lastFetch) < this.cacheTimeout) {\n return this.catalog;\n }\n\n // Fetch new catalog\n this.catalog = await this.fetchCatalog();\n this.lastFetch = now;\n \n return this.catalog;\n }\n\n async getModels(): Promise<string[]> {\n const catalog = await this.getCatalog();\n return [\n ...Object.keys(catalog.tts),\n ...Object.keys(catalog.stt),\n ...Object.keys(catalog.llm)\n ];\n }\n\n async getPricing(): Promise<Record<string, string>> {\n const catalog = await this.getCatalog();\n const pricing: Record<string, string> = {};\n \n Object.entries(catalog.tts).forEach(([key, model]) => {\n pricing[`tts/${key}`] = model.pricing;\n });\n \n Object.entries(catalog.stt).forEach(([key, model]) => {\n pricing[`stt/${key}`] = model.pricing;\n });\n \n Object.entries(catalog.llm).forEach(([key, model]) => {\n pricing[`llm/${key}`] = model.pricing;\n });\n \n return pricing;\n }\n\n // Force refresh the catalog\n async refresh(): Promise<void> {\n this.catalog = null;\n this.lastFetch = 0;\n await this.getCatalog();\n }\n}\n\nexport const catalogManager = new CatalogManager();","import { VoiceAI } from './client';\nimport { tts } from './tts';\nimport { stt } from './stt';\nimport { llm } from './llm';\nimport { auth } from './auth';\nimport { warmup } from './warmup';\n\nexport { VoiceAI, tts, stt, llm, auth, warmup };\n\nexport * from './types';\nexport * from './providers';\n\nexport default VoiceAI;","export interface VoiceAIConfig {\n apiKey: string;\n baseUrl?: string;\n timeout?: number; // milliseconds, default 30000 (30s)\n}\n\nexport class VoiceAI {\n private static instance: VoiceAI;\n private config: VoiceAIConfig;\n\n constructor(config: VoiceAIConfig) {\n this.config = {\n baseUrl: 'https://api.slng.ai',\n ...config,\n };\n VoiceAI.instance = this;\n }\n\n static getInstance(): VoiceAI {\n if (!VoiceAI.instance) {\n throw new Error(\n 'VoiceAI not initialized. Please call new VoiceAI({ apiKey: \"your-key\" }) first.\\n' +\n 'Get your API key at https://slng.ai/signup'\n );\n }\n return VoiceAI.instance;\n }\n\n getConfig(): VoiceAIConfig {\n return this.config;\n }\n\n updateApiKey(apiKey: string): void {\n this.config.apiKey = apiKey;\n }\n}","import { VoiceAI } from './client';\nimport { providers } from './providers';\n\nexport interface TTSOptions {\n voice?: string;\n language?: string;\n stream?: boolean;\n format?: 'mp3' | 'wav' | 'aac' | 'flac';\n temperature?: number;\n speed?: number;\n [key: string]: any;\n}\n\nexport interface TTSResult {\n audio: ArrayBuffer | ReadableStream;\n duration?: number;\n format?: string;\n}\n\nasync function synthesize(\n text: string,\n model: string,\n options: TTSOptions = {}\n): Promise<TTSResult> {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n \n const provider = providers.tts[model];\n if (!provider) {\n throw new Error(\n `Model \"${model}\" not found. Available models: ${Object.keys(providers.tts).join(', ')}\\n` +\n `Need a different model? Contact founders at hello@slng.ai`\n );\n }\n\n return provider.synthesize(text, options, config);\n}\n\nexport const tts = {\n async synthesize(text: string, model: string, options?: TTSOptions): Promise<TTSResult> {\n return synthesize(text, model, options);\n },\n \n vui: (text: string, options?: TTSOptions) => \n synthesize(text, 'vui', options),\n \n orpheus: (text: string, options?: TTSOptions) => \n synthesize(text, 'orpheus', options),\n \n koroko: (text: string, options?: TTSOptions) => \n synthesize(text, 'koroko', options),\n \n xtts: (text: string, options?: TTSOptions & { speakerVoice: string }) => \n synthesize(text, 'xtts-v2', options),\n \n mars6: (text: string, options?: TTSOptions & { audioRef: string }) => \n synthesize(text, 'mars6', options),\n \n orpheusIndic: (text: string, options?: TTSOptions & { language: string }) => {\n if (!options?.language) {\n throw new Error('Orpheus Indic requires language option (hi, ta, te, bn, mr, gu, kn, ml)');\n }\n return synthesize(text, 'orpheus-indic', options);\n },\n \n elevenlabs: {\n multiV2: (text: string, options?: TTSOptions) => \n synthesize(text, 'elevenlabs/multi-v2', options),\n \n turbo: (text: string, options?: TTSOptions) => \n synthesize(text, 'elevenlabs/turbo-v2-5', options),\n \n v3: (text: string, options?: TTSOptions) => \n synthesize(text, 'elevenlabs/v3', options),\n \n flash: (text: string, options?: TTSOptions) => \n synthesize(text, 'elevenlabs/flash-v2-5', options),\n },\n\n models: Object.keys(providers.tts),\n \n getVoices: (model: string): string[] => {\n const provider = providers.tts[model];\n return provider?.voices || [];\n },\n \n getLanguages: (model: string): string[] => {\n const provider = providers.tts[model];\n return provider?.languages || ['en'];\n },\n};","import { TTSProviders } from './tts';\nimport { STTProviders } from './stt';\nimport { LLMProviders } from './llm';\n\nexport const providers = {\n tts: TTSProviders,\n stt: STTProviders,\n llm: LLMProviders,\n};\n\nexport * from './tts';\nexport * from './stt';\nexport * from './llm';","import { VoiceAIConfig } from '../client';\nimport { TTSOptions, TTSResult } from '../tts';\nimport { makeRequest } from '../utils/request';\n\nexport interface TTSProvider {\n synthesize: (text: string, options: TTSOptions, config: VoiceAIConfig) => Promise<TTSResult>;\n voices?: string[];\n languages?: string[];\n}\n\nexport const TTSProviders: Record<string, TTSProvider> = {\n 'vui': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/vui',\n method: 'POST',\n data: { text, ...options },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['default', 'female_01', 'male_01'],\n languages: ['en'],\n },\n\n 'orpheus': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/orpheus',\n method: 'POST',\n data: { \n prompt: text,\n voice: options.voice || 'tara',\n output_language: options.language,\n ...options \n },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['tara', 'leah', 'jess', 'leo', 'dan', 'mia', 'zac', 'zoe', 'pierre', 'amelie', 'marie', 'jana', 'thomas', 'max'],\n languages: ['en', 'fr', 'de', 'ko', 'zh', 'es', 'it', 'hi'],\n },\n\n 'koroko': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/koroko',\n method: 'POST',\n data: { text, ...options },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n languages: ['en'],\n },\n\n 'xtts-v2': {\n synthesize: async (text, options: any, config) => {\n if (!options.speakerVoice) {\n throw new Error('XTTS-v2 requires speakerVoice option (base64 audio for voice cloning)');\n }\n const audio = await makeRequest({\n url: '/v1/tts/xtts-v2',\n method: 'POST',\n data: { \n text,\n speaker_voice: options.speakerVoice,\n language: options.language || 'en',\n ...options \n },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'tr', 'ru', 'nl', 'cs', 'ar', 'zh', 'ja', 'ko', 'hu', 'hi'],\n },\n\n 'mars6': {\n synthesize: async (text, options: any, config) => {\n if (!options.audioRef) {\n throw new Error('MARS6 requires audioRef option (base64 audio for voice cloning)');\n }\n if (!options.language) {\n throw new Error('MARS6 requires language option (e.g., \"en-us\")');\n }\n const audio = await makeRequest({\n url: '/v1/tts/mars6',\n method: 'POST',\n data: { \n text,\n audio_ref: options.audioRef,\n language: options.language,\n ref_text: options.refText,\n ...options \n },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n languages: ['en-us', 'fr-fr', 'de-de', 'es-es', 'it-it', 'pt-pt', 'zh-cn', 'ja-jp', 'ko-kr', 'nl-nl'],\n },\n\n 'elevenlabs/multi-v2': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/elevenlabs/multi-v2',\n method: 'POST',\n data: { text, ...options },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul', 'Domi', 'Dave', 'Fin', 'Bella'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'hi', 'ar', 'zh', 'ja', 'ko'],\n },\n\n 'elevenlabs/turbo-v2-5': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/elevenlabs/turbo-v2-5',\n method: 'POST',\n data: { text, ...options },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt'],\n },\n\n 'elevenlabs/v3': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/elevenlabs/v3',\n method: 'POST',\n data: { text, ...options },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul', 'Domi', 'Dave', 'Fin', 'Bella'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl', 'hi'],\n },\n\n 'elevenlabs/flash-v2-5': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/elevenlabs/flash-v2-5',\n method: 'POST',\n data: { text, ...options },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['Rachel', 'Drew', 'Clyde', 'Paul'],\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'pl'],\n },\n\n 'orpheus-indic': {\n synthesize: async (text, options, config) => {\n const audio = await makeRequest({\n url: '/v1/tts/in/orpheus-indic',\n method: 'POST',\n data: { \n prompt: text,\n voice: options.voice,\n output_language: options.language || 'hi',\n output_style: options.style,\n speed: options.speed,\n ...options \n },\n responseType: options.stream ? 'stream' : 'arraybuffer',\n config,\n });\n return { audio };\n },\n voices: ['hindi_male', 'hindi_female', 'tamil_male', 'tamil_female', 'telugu_male', 'bengali_female', 'marathi_male', 'gujarati_female', 'kannada_male', 'malayalam_female'],\n languages: ['hi', 'ta', 'te', 'bn', 'mr', 'gu', 'kn', 'ml'],\n },\n\n 'twi-speecht5': {\n synthesize: async (text, options: any, config) => {\n if (!options.speakerEmbedding || options.speakerEmbedding.length !== 512) {\n throw new Error('Twi-SpeechT5 requires speakerEmbedding option (512-dimensional vector)');\n }\n const response = await makeRequest({\n url: '/v1/tts/twi-speecht5',\n method: 'POST',\n data: { \n text,\n speaker_embedding: options.speakerEmbedding,\n },\n responseType: 'json',\n config,\n });\n \n const audioArray = new Float32Array(response.audio);\n return { audio: audioArray.buffer };\n },\n languages: ['tw'],\n },\n};","import axios, { AxiosRequestConfig } from 'axios';\nimport { VoiceAIConfig } from '../client';\n\nexport interface RequestOptions {\n url: string;\n method: 'GET' | 'POST' | 'PUT' | 'DELETE';\n data?: any;\n headers?: Record<string, string>;\n responseType?: 'json' | 'arraybuffer' | 'stream';\n config: VoiceAIConfig;\n modelTimeout?: number; // Model-specific timeout override\n}\n\n// Model-specific timeout settings (in milliseconds)\nconst MODEL_TIMEOUTS: Record<string, number> = {\n 'orpheus': 90000, // 90s - can be slow on cold start\n 'orpheus-indic': 90000, // 90s - infrastructure cold start\n 'xtts-v2': 90000, // 90s - voice cloning takes time\n 'mars6': 90000, // 90s - complex processing\n 'elevenlabs/v3': 60000, // 60s\n 'whisper-v3': 120000, // 120s - large audio files\n 'llama-4-scout': 60000, // 60s - LLM generation\n};\n\nfunction getTimeout(url: string, config: VoiceAIConfig, modelTimeout?: number): number {\n // Priority: modelTimeout > model-specific > user config > default\n if (modelTimeout) return modelTimeout;\n \n // Check if URL matches a known model\n for (const [model, timeout] of Object.entries(MODEL_TIMEOUTS)) {\n if (url.includes(model.replace('/', '/'))) {\n return timeout;\n }\n }\n \n return config.timeout || 30000; // Default 30s\n}\n\nexport async function makeRequest(options: RequestOptions): Promise<any> {\n const { url, method, data, headers, responseType = 'json', config, modelTimeout } = options;\n\n const timeout = getTimeout(url, config, modelTimeout);\n \n const axiosConfig: AxiosRequestConfig = {\n url,\n method,\n baseURL: config.baseUrl || 'https://api.slng.ai',\n headers: {\n 'Authorization': `Bearer ${config.apiKey}`,\n 'User-Agent': 'VoiceAI-SDK/0.1.2',\n ...headers,\n },\n data,\n responseType: responseType as any,\n timeout,\n };\n\n try {\n const response = await axios(axiosConfig);\n return response.data;\n } catch (error: any) {\n if (error.code === 'ECONNABORTED' || error.code === 'ETIMEDOUT') {\n const isKnownSlowModel = Object.keys(MODEL_TIMEOUTS).some(model => \n options.url.includes(model.replace('/', '/'))\n );\n \n if (isKnownSlowModel) {\n throw new Error(\n `Request timed out after ${timeout/1000}s. Model may be starting up (cold start).\\n` +\n `First calls can take 60-90 seconds. Please retry in a moment.\\n` +\n `Tip: You can increase timeout with new VoiceAI({ timeout: 120000 })`\n );\n } else {\n throw new Error(\n `Request timed out after ${timeout/1000}s.\\n` +\n `Try again or increase timeout with new VoiceAI({ timeout: 60000 })`\n );\n }\n }\n \n if (error.response) {\n const { status, data } = error.response;\n const message = data?.error || data?.message || 'Request failed';\n \n if (status === 401) {\n throw new Error(\n `Authentication failed: ${message}\\n` +\n `Please check your API key. Get one at https://slng.ai/signup`\n );\n } else if (status === 402) {\n throw new Error(\n `Insufficient credits: ${message}\\n` +\n `Add credits at https://slng.ai/dashboard`\n );\n } else if (status === 429) {\n throw new Error(\n `Rate limit exceeded: ${message}\\n` +\n `Please slow down your requests or upgrade your plan at https://slng.ai/pricing`\n );\n } else if (status === 400) {\n throw new Error(`Invalid request: ${message}`);\n } else if (status >= 500) {\n throw new Error(\n `Server error (${status}): ${message}\\n` +\n `The model service may be temporarily unavailable. Please retry.\\n` +\n `If this persists, contact hello@slng.ai`\n );\n } else {\n throw new Error(\n `API Error (${status}): ${message}\\n` +\n `Need help? Contact founders at hello@slng.ai`\n );\n }\n } else if (error.request) {\n throw new Error(\n 'Network error: Unable to reach SLNG.AI servers.\\n' +\n 'Please check your internet connection.'\n );\n } else {\n throw new Error(`Unexpected error: ${error.message}`);\n }\n }\n}","import { VoiceAIConfig } from '../client';\nimport { STTOptions, STTResult } from '../stt';\nimport { makeRequest } from '../utils/request';\nimport FormData from 'form-data';\n\nexport interface STTProvider {\n transcribe: (audio: File | Blob | ArrayBuffer | string, options: STTOptions, config: VoiceAIConfig) => Promise<STTResult>;\n languages?: string[];\n}\n\nexport const STTProviders: Record<string, STTProvider> = {\n 'whisper-v3': {\n transcribe: async (audio, options, config) => {\n const formData = new FormData();\n \n if (audio instanceof File) {\n formData.append('audio', audio, audio.name);\n } else if (audio instanceof Blob) {\n formData.append('audio', audio, 'audio.wav');\n } else if (audio instanceof ArrayBuffer) {\n const blob = new Blob([audio]);\n formData.append('audio', blob, 'audio.wav');\n } else if (typeof audio === 'string') {\n formData.append('audio', audio);\n }\n\n if (options.language) {\n formData.append('language', options.language);\n }\n\n const response = await makeRequest({\n url: '/v1/stt/whisper-v3',\n method: 'POST',\n data: formData,\n headers: formData.getHeaders(),\n responseType: 'json',\n config,\n });\n\n return {\n text: response.text,\n confidence: response.confidence,\n language: response.language || options.language,\n segments: response.segments,\n };\n },\n languages: ['en', 'es', 'fr', 'de', 'it', 'pt', 'ru', 'zh', 'ja', 'ko', 'ar', 'hi'],\n },\n\n 'kyutai': {\n transcribe: async (audio, options, config) => {\n const formData = new FormData();\n \n if (audio instanceof File) {\n formData.append('audio', audio, audio.name);\n } else if (audio instanceof Blob) {\n formData.append('audio', audio, 'audio.wav');\n } else if (audio instanceof ArrayBuffer) {\n const blob = new Blob([audio]);\n formData.append('audio', blob, 'audio.wav');\n } else if (typeof audio === 'string') {\n formData.append('audio', audio);\n }\n\n if (options.language) {\n if (!['en', 'fr'].includes(options.language)) {\n throw new Error('Kyutai only supports English (en) and French (fr)');\n }\n formData.append('language', options.language);\n }\n\n if (options.timestamps !== undefined) {\n formData.append('timestamps', String(options.timestamps));\n }\n\n const response = await makeRequest({\n url: '/v1/stt/in/kyutai',\n method: 'POST',\n data: formData,\n headers: formData.getHeaders(),\n responseType: 'json',\n config,\n });\n\n return {\n text: response.text,\n confidence: response.confidence,\n language: response.language || options.language,\n segments: response.segments,\n };\n },\n languages: ['en', 'fr'],\n },\n\n 'general': {\n transcribe: async (audio, options, config) => {\n const formData = new FormData();\n \n if (audio instanceof File) {\n formData.append('audio', audio, audio.name);\n } else if (audio instanceof Blob) {\n formData.append('audio', audio, 'audio.wav');\n } else if (audio instanceof ArrayBuffer) {\n const blob = new Blob([audio]);\n formData.append('audio', blob, 'audio.wav');\n } else if (typeof audio === 'string') {\n formData.append('audio', audio);\n }\n\n if (options.language) {\n formData.append('config', JSON.stringify({ language: options.language }));\n }\n\n const response = await makeRequest({\n url: '/v1/stt',\n method: 'POST',\n data: formData,\n headers: formData.getHeaders(),\n responseType: 'json',\n config,\n });\n\n return {\n text: response.text,\n confidence: response.confidence,\n language: response.language || options.language,\n };\n },\n languages: ['en'],\n },\n};","import { VoiceAIConfig } from '../client';\nimport { LLMMessage, LLMOptions, LLMResult } from '../llm';\nimport { makeRequest } from '../utils/request';\n\nexport interface LLMProvider {\n complete: (messages: LLMMessage[], options: LLMOptions, config: VoiceAIConfig) => Promise<LLMResult | ReadableStream>;\n}\n\nexport const LLMProviders: Record<string, LLMProvider> = {\n 'llama-4-scout': {\n complete: async (messages, options, config) => {\n const response = await makeRequest({\n url: '/v1/llm/llama-4-scout',\n method: 'POST',\n data: {\n messages,\n temperature: options.temperature,\n max_tokens: options.maxTokens,\n top_p: options.topP,\n stream: options.stream,\n },\n responseType: options.stream ? 'stream' : 'json',\n config,\n });\n\n if (options.stream) {\n return response as ReadableStream;\n }\n\n return {\n content: response.choices?.[0]?.message?.content || response.response,\n usage: response.usage ? {\n promptTokens: response.usage.prompt_tokens,\n completionTokens: response.usage.completion_tokens,\n totalTokens: response.usage.total_tokens,\n } : undefined,\n };\n },\n },\n\n 'general': {\n complete: async (messages, options, config) => {\n const prompt = messages.map(m => `${m.role}: ${m.content}`).join('\\n');\n \n const response = await makeRequest({\n url: '/v1/llm',\n method: 'POST',\n data: {\n prompt,\n model: options.model,\n },\n responseType: 'json',\n config,\n });\n\n return {\n content: response.response,\n };\n },\n },\n};","import { VoiceAI } from './client';\nimport { providers } from './providers';\n\nexport interface STTOptions {\n language?: string;\n format?: string;\n timestamps?: boolean;\n diarization?: boolean;\n [key: string]: any;\n}\n\nexport interface STTResult {\n text: string;\n confidence?: number;\n language?: string;\n segments?: Array<{\n text: string;\n start: number;\n end: number;\n confidence?: number;\n }>;\n}\n\nasync function transcribe(\n audio: File | Blob | ArrayBuffer | string,\n model: string,\n options: STTOptions = {}\n): Promise<STTResult> {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n \n const provider = providers.stt[model];\n if (!provider) {\n throw new Error(\n `Model \"${model}\" not found. Available models: ${Object.keys(providers.stt).join(', ')}\\n` +\n `Need a different model? Contact founders at hello@slng.ai`\n );\n }\n\n return provider.transcribe(audio, options, config);\n}\n\nexport const stt = {\n async transcribe(audio: File | Blob | ArrayBuffer | string, model: string, options?: STTOptions): Promise<STTResult> {\n return transcribe(audio, model, options);\n },\n \n whisper: (audio: File | Blob | ArrayBuffer | string, options?: STTOptions) => \n transcribe(audio, 'whisper-v3', options),\n \n kyutai: (audio: File | Blob | ArrayBuffer | string, options?: STTOptions) => \n transcribe(audio, 'kyutai', options),\n \n models: Object.keys(providers.stt),\n \n getLanguages: (model: string): string[] => {\n const provider = providers.stt[model];\n return provider?.languages || ['en'];\n },\n};","import { VoiceAI } from './client';\nimport { providers } from './providers';\n\nexport interface LLMMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\nexport interface LLMOptions {\n temperature?: number;\n maxTokens?: number;\n topP?: number;\n stream?: boolean;\n [key: string]: any;\n}\n\nexport interface LLMResult {\n content: string;\n usage?: {\n promptTokens: number;\n completionTokens: number;\n totalTokens: number;\n };\n}\n\nasync function complete(\n messages: LLMMessage[] | string,\n model: string,\n options: LLMOptions = {}\n): Promise<LLMResult | ReadableStream> {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n \n const provider = providers.llm[model];\n if (!provider) {\n throw new Error(\n `Model \"${model}\" not found. Available models: ${Object.keys(providers.llm).join(', ')}\\n` +\n `Need a different model? Contact founders at hello@slng.ai`\n );\n }\n\n const normalizedMessages = typeof messages === 'string' \n ? [{ role: 'user' as const, content: messages }]\n : messages;\n\n return provider.complete(normalizedMessages, options, config);\n}\n\nexport const llm = {\n async complete(messages: LLMMessage[] | string, model: string, options?: LLMOptions): Promise<LLMResult | ReadableStream> {\n return complete(messages, model, options);\n },\n \n llamaScout: (messages: LLMMessage[] | string, options?: LLMOptions) => \n complete(messages, 'llama-4-scout', options),\n \n models: Object.keys(providers.llm),\n};","import { makeRequest } from './utils/request';\nimport { VoiceAI } from './client';\n\nexport interface SignupOptions {\n email: string;\n password?: string;\n referralCode?: string;\n}\n\nexport interface LoginOptions {\n email: string;\n password: string;\n}\n\nexport interface AccountInfo {\n email: string;\n apiKey: string;\n credits: number;\n plan: string;\n usage?: {\n tts: number;\n stt: number;\n llm: number;\n };\n}\n\nexport class Auth {\n private static signupUrl = 'https://slng.ai/signup';\n private static dashboardUrl = 'https://slng.ai/dashboard';\n\n static async signup(_options: SignupOptions): Promise<{ message: string; apiKey?: string }> {\n console.log(`\n╔════════════════════════════════════════════╗\n║ Welcome to SLNG.AI Voice Platform! ║\n╚════════════════════════════════════════════╝\n\nSign up at: ${this.signupUrl}\n\nAfter signing up:\n1. Get your API key from the dashboard\n2. Initialize the SDK:\n\n new VoiceAI({ apiKey: 'your-api-key' });\n\n3. Start building amazing voice experiences!\n\nNeed help? Contact founders at hello@slng.ai\n`);\n\n return {\n message: `Please complete signup at ${this.signupUrl}`,\n };\n }\n\n static async getAccount(): Promise<AccountInfo | null> {\n try {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n\n const response = await makeRequest({\n url: '/v1/account',\n method: 'GET',\n config,\n responseType: 'json',\n });\n\n return response;\n } catch (error: any) {\n if (error.message.includes('Authentication failed')) {\n console.log(`\nNo API key found or invalid key.\n\nGet your API key:\n1. Sign up at ${this.signupUrl}\n2. Visit dashboard at ${this.dashboardUrl}\n3. Copy your API key\n4. Initialize: new VoiceAI({ apiKey: 'your-key' });\n`);\n return null;\n }\n throw error;\n }\n }\n\n static async checkCredits(): Promise<number | null> {\n const account = await this.getAccount();\n return account?.credits || null;\n }\n\n static showDashboard(): void {\n console.log(`\n╔═══════════════════════════════════════╗\n║ SLNG.AI Dashboard ║\n╚═══════════════════════════════════════╝\n\nManage your account: ${this.dashboardUrl}\n\n• View API keys\n• Check credit balance\n• Monitor usage\n• Upgrade plan\n• Access documentation\n\nNeed more credits? Visit ${this.dashboardUrl}/credits\nQuestions? Email hello@slng.ai\n`);\n }\n\n static async showPricing(): Promise<void> {\n try {\n const { catalogManager } = await import('./utils/catalog');\n const catalog = await catalogManager.getCatalog();\n \n console.log(`\n╔═══════════════════════════════════════╗\n║ SLNG.AI Pricing ║\n╚═══════════════════════════════════════╝\n\nSimple, transparent pricing:\n\nTEXT-TO-SPEECH (TTS):`);\n \n Object.entries(catalog.tts).forEach(([_key, model]) => {\n console.log(`• ${model.name}: ${model.pricing}`);\n });\n \n console.log(`\nSPEECH-TO-TEXT (STT):`);\n Object.entries(catalog.stt).forEach(([_key, model]) => {\n console.log(`• ${model.name}: ${model.pricing}`);\n });\n \n console.log(`\nLANGUAGE MODELS (LLM):`);\n Object.entries(catalog.llm).forEach(([_key, model]) => {\n console.log(`• ${model.name}: ${model.pricing}`);\n });\n \n console.log(`\nView full pricing: https://slng.ai/pricing\nGet started: ${this.signupUrl}\n`);\n } catch (error) {\n // Fallback to web link if catalog fails\n console.log(`View current pricing: https://slng.ai/pricing`);\n }\n }\n\n static async showModels(): Promise<void> {\n try {\n const { catalogManager } = await import('./utils/catalog');\n const catalog = await catalogManager.getCatalog();\n \n console.log(`\n╔═══════════════════════════════════════╗\n║ Available Voice AI Models ║\n╚═══════════════════════════════════════╝\n\nTEXT-TO-SPEECH (TTS):`);\n \n Object.entries(catalog.tts).forEach(([key, model]) => {\n console.log(`• ${key} - ${model.description}`);\n if (model.languages) {\n console.log(` Languages: ${model.languages.slice(0, 5).join(', ')}${model.languages.length > 5 ? '...' : ''}`);\n }\n });\n \n console.log(`\nSPEECH-TO-TEXT (STT):`);\n Object.entries(catalog.stt).forEach(([key, model]) => {\n console.log(`• ${key} - ${model.description}`);\n });\n \n console.log(`\nLANGUAGE MODELS (LLM):`);\n Object.entries(catalog.llm).forEach(([key, model]) => {\n console.log(`• ${key} - ${model.description}`);\n });\n \n console.log(`\nNeed a different model? \nEmail us at hello@slng.ai\n\nLast updated: ${new Date(catalog.lastUpdated).toLocaleDateString()}\n`);\n } catch (error) {\n // Fallback to web link if catalog fails\n console.log(`View available models: https://slng.ai/models`);\n }\n }\n}\n\nexport const auth = Auth;","import { VoiceAI } from './client';\nimport { makeRequest } from './utils/request';\n\n/**\n * Warmup utilities for pre-warming models to avoid cold start delays\n */\nexport class Warmup {\n /**\n * Pre-warm a TTS model to avoid cold start delays\n * @param model - The TTS model to warm up (e.g., 'orpheus', 'elevenlabs/multi-v2')\n * @returns Promise that resolves when the model is ready\n */\n static async tts(model: string): Promise<void> {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n \n try {\n // Send a minimal request to wake the model\n await makeRequest({\n url: `/v1/tts/${model.replace('/', '/')}`,\n method: 'POST',\n data: { \n text: 'Test', \n warmup: true // Signal this is a warmup request\n },\n config,\n modelTimeout: 120000, // 2 minutes for warmup\n responseType: 'json',\n });\n \n console.log(`✓ Model ${model} is warmed up and ready`);\n } catch (error: any) {\n // If it's just a warmup, we can ignore some errors\n if (error.message.includes('timed out')) {\n console.log(`⚠ Model ${model} is warming up (may take 60-90s for first call)`);\n } else {\n throw error;\n }\n }\n }\n\n /**\n * Pre-warm an STT model\n * @param model - The STT model to warm up (e.g., 'whisper-v3')\n */\n static async stt(model: string): Promise<void> {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n \n try {\n // Create minimal audio data (1 second of silence)\n const sampleRate = 16000;\n const duration = 1;\n const audioData = new Float32Array(sampleRate * duration);\n \n await makeRequest({\n url: `/v1/stt/${model}`,\n method: 'POST',\n data: {\n audio: Buffer.from(audioData.buffer).toString('base64'),\n warmup: true\n },\n config,\n modelTimeout: 120000,\n responseType: 'json',\n });\n \n console.log(`✓ Model ${model} is warmed up and ready`);\n } catch (error: any) {\n if (error.message.includes('timed out')) {\n console.log(`⚠ Model ${model} is warming up (may take 60-90s for first call)`);\n } else {\n // Ignore warmup-specific errors\n console.log(`✓ Model ${model} warmup attempted`);\n }\n }\n }\n\n /**\n * Pre-warm an LLM model\n * @param model - The LLM model to warm up (e.g., 'llama-4-scout')\n */\n static async llm(model: string): Promise<void> {\n const client = VoiceAI.getInstance();\n const config = client.getConfig();\n \n try {\n await makeRequest({\n url: `/v1/llm/${model}`,\n method: 'POST',\n data: {\n messages: [{ role: 'user', content: 'Hi' }],\n max_tokens: 1,\n warmup: true\n },\n config,\n modelTimeout: 120000,\n responseType: 'json',\n });\n \n console.log(`✓ Model ${model} is warmed up and ready`);\n } catch (error: any) {\n if (error.message.includes('timed out')) {\n console.log(`⚠ Model ${model} is warming up (may take 60-90s for first call)`);\n } else {\n console.log(`✓ Model ${model} warmup attempted`);\n }\n }\n }\n\n /**\n * Pre-warm multiple models in parallel\n * @param models - Array of model identifiers with their types\n * @example\n * await Warmup.multiple([\n * { type: 'tts', model: 'orpheus' },\n * { type: 'stt', model: 'whisper-v3' },\n * { type: 'llm', model: 'llama-4-scout' }\n * ]);\n */\n static async multiple(models: Array<{ type: 'tts' | 'stt' | 'llm', model: string }>): Promise<void> {\n console.log(`Warming up ${models.length} models...`);\n \n const promises = models.map(({ type, model }) => {\n switch (type) {\n case 'tts':\n return this.tts(model);\n case 'stt':\n return this.stt(model);\n case 'llm':\n return this.llm(model);\n default:\n return Promise.resolve();\n }\n });\n \n await Promise.allSettled(promises);\n console.log('✓ All models warmed up');\n }\n}\n\nexport const warmup = Warmup;","export type { TTSOptions, TTSResult } from './tts';\nexport type { STTOptions, STTResult } from './stt';\nexport type { LLMMessage, LLMOptions, LLMResult } from './llm';\nexport type { VoiceAIConfig } from './client';\nexport type { SignupOptions, LoginOptions, AccountInfo } from './auth';\n\nexport type AudioFormat = 'mp3' | 'wav' | 'aac' | 'flac' | 'ogg' | 'pcm';\n\nexport type TTSModel = \n | 'vui'\n | 'orpheus'\n | 'orpheus-indic'\n | 'koroko'\n | 'xtts-v2'\n | 'mars6'\n | 'elevenlabs/multi-v2'\n | 'elevenlabs/turbo-v2-5'\n | 'elevenlabs/v3'\n | 'elevenlabs/ttv-v3'\n | 'elevenlabs/flash-v2-5'\n | 'twi-speecht5';\n\nexport type STTModel = \n | 'whisper-v3'\n | 'kyutai'\n | 'general';\n\nexport type LLMModel = \n | 'llama-4-scout'\n | 'general';"],"mappings":"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