@elizaos/plugin-tts 0.1.9 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1,13 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts"],"sourcesContent":["import { elizaLogger } from \"@elizaos/core\";\nimport type {\n Action,\n HandlerCallback,\n IAgentRuntime,\n Memory,\n Plugin,\n State,\n} from \"@elizaos/core\";\nimport { fal } from \"@fal-ai/client\";\nimport { FAL_CONSTANTS, VOICE_MAP, getRandomVoice } from \"./constants\";\n\nimport * as fs from \"node:fs\";\nimport { Buffer } from \"node:buffer\";\nimport * as path from \"node:path\";\nimport * as process from \"node:process\";\nimport { detect } from 'langdetect';\n\nconst generateTTS = async (prompt: string, voice: string, runtime: IAgentRuntime) => {\n\n process.env.FAL_KEY = FAL_CONSTANTS.API_KEY_SETTING || runtime.getSetting(\"FAL_API_KEY\");\n\n try {\n elizaLogger.log(\"Starting TTS generation with prompt:\", prompt);\n\n const response = await fal.subscribe(FAL_CONSTANTS.API_TTS_ENDPOINT, {\n input: {\n input: prompt,\n voice: voice\n },\n logs: true,\n onQueueUpdate: (update) => {\n if (update.status === \"IN_PROGRESS\") {\n update.logs\n .map((log) => log.message)\n .forEach(elizaLogger.debug);\n }\n },\n });\n\n elizaLogger.debug(\n \"Generation request successful, received response:\",\n response\n );\n\n return { success: true, data: response.data };\n } catch (error) {\n elizaLogger.error(\"TTS generation error:\", error);\n return {\n success: false,\n error: error.message || \"Unknown error occurred\",\n };\n }\n};\n\nconst TTSGeneration: Action = {\n name: \"GENERATE_TTS\",\n similes: [\n \"TTS_GENERATION\",\n \"CREATE_TTS\",\n \"TEXT2SPEECH\",\n \"T2S\",\n \"TEXT_TO_SPEECH\",\n \"AUDIO_CREATE\",\n ],\n description: \"Generate a tts audio based on a text prompt\",\n validate: async (runtime: IAgentRuntime, _message: Memory) => {\n elizaLogger.debug(\"Validating TTS action\");\n const FalApiKey = runtime.getSetting(\"FAL_API_KEY\");\n elizaLogger.debug(\"FAL_API_KEY present:\", !!FalApiKey);\n return !!FalApiKey;\n },\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state: State,\n _options: Record<string, unknown>,\n callback: HandlerCallback\n ) => {\n elizaLogger.debug(\"TTS request:\", message);\n // Clean up the prompt by removing mentions and commands\n const TTSPrompt = message.content.text\n .replace(/<@\\d+>/g, \"\") // Remove mentions\n .replace(/generate TTS|create TTS|make TTS|render TTS/gi, \"\")\n .trim();\n\n if (!TTSPrompt || TTSPrompt.length < 3) {\n callback({ text: \"Please input a word at least of length 3\" });\n return;\n }\n\n elizaLogger.debug(\"TTS prompt:\", TTSPrompt);\n\n callback({\n text: `I'll generate an audio based on your prompt: \"${TTSPrompt}\". This might take a few seconds...`,\n });\n\n let target_voice: string;\n try {\n const language = detect(TTSPrompt);\n if (language && language.length > 0) {\n const voice_subject = VOICE_MAP[language[0].lang];\n target_voice = getRandomVoice(voice_subject).fullName;\n } else {\n throw new Error(\"Language detection failed, no language detected.\");\n }\n } catch (error) {\n elizaLogger.error(\"Language detection error:\", error);\n\n // const defaultVoice = VOICE_MAP['en'];\n const defaultVoice = VOICE_MAP.en;\n\n target_voice = getRandomVoice(defaultVoice).fullName;\n }\n\n elizaLogger.debug(\"Starting TTS generation with prompt:\", TTSPrompt, \"and voice:\", target_voice);\n\n try {\n const result = await generateTTS(TTSPrompt, target_voice, runtime);\n\n if (result.success && result.data.audio.url) {\n const cachedFile = `content_cache/tts_${result.data.audio.file_name}`;\n if (fs.existsSync(cachedFile)) {\n elizaLogger.debug(\"Using cached audio:\", cachedFile);\n } else {\n const response = await fetch(result.data.audio.url);\n const arrayBuffer = await response.arrayBuffer();\n\n const directoryPath = path.dirname(cachedFile);\n if (!fs.existsSync(directoryPath)) {\n fs.mkdirSync(directoryPath, { recursive: true });\n }\n\n fs.writeFileSync(cachedFile, Buffer.from(arrayBuffer));\n elizaLogger.debug(\"Audio Duration:\", result.data.audio.duration);\n }\n\n callback({\n text: \"TTS Success! Here's your generated audio!\",\n attachments: [\n {\n id: crypto.randomUUID(),\n url: result.data.audio.url,\n title: \"TTS Generation\",\n source: \"TTSGeneration\",\n description: TTSPrompt,\n text: TTSPrompt,\n },\n ],\n }, [cachedFile]);\n } else {\n callback({ text: `TTS generation failed: ${result.error}`, error: true });\n }\n } catch (error) {\n elizaLogger.error(`Failed to generate TTS. Error: ${error}`);\n callback({ text: `TTS generation failed: ${error.message}`, error: true });\n }\n },\n examples: [\n [\n { user: \"{{user1}}\", content: { text: \"Generate a TTS of prompt: Hello world!\" } },\n { user: \"{{agentName}}\", content: { text: \"I'll call a TTS to generate an audio based on your input prompt\", action: \"CREATE_TTS\" } },\n ],\n [\n { user: \"{{user1}}\", content: { text: \"Please do TTS to a prompt: Sam is busy now\" } },\n { user: \"{{agentName}}\", content: { text: \"Ok, please wait for the tts generation~\", action: \"AUDIO_CREATE\" } },\n ],\n ],\n};\n\nexport const TTSGenerationPlugin: Plugin = {\n name: \"TTSGeneration\",\n description: \"Generate TTS using PlayAI tts (v3)\",\n actions: [TTSGeneration],\n evaluators: [],\n providers: [],\n};","export const FAL_CONSTANTS = {\n API_TTS_ENDPOINT: \"fal-ai/playai/tts/v3\",\n API_KEY_SETTING: \"FAL_API_KEY\", // The setting name to fetch from runtime\n};\n\nexport interface VoiceOption {\n name: string;\n style: \"Conversational\" | \"Narrative\" | \"Advertising\" | \"Meditation\";\n region?: string;\n fullName: string; \n }\n\nexport const VOICE_MAP: Record<string, VoiceOption[]> = {\n 'en': [\n { \n name: \"Jennifer\", \n style: \"Conversational\", \n region: \"US/American\",\n fullName: \"Jennifer (English (US)/American)\"\n },\n { \n name: \"Dexter\", \n style: \"Conversational\", \n region: \"US/American\",\n fullName: \"Dexter (English (US)/American)\"\n },\n { \n name: \"Ava\", \n style: \"Conversational\", \n region: \"AU/Australian\",\n fullName: \"Ava (English (AU)/Australian)\"\n },\n { \n name: \"Tilly\", \n style: \"Conversational\", \n region: \"AU/Australian\",\n fullName: \"Tilly (English (AU)/Australian)\"\n },\n { \n name: \"Charlotte\", \n style: \"Advertising\", \n region: \"CA/Canadian\",\n fullName: \"Charlotte (Advertising) (English (CA)/Canadian)\"\n },\n { \n name: \"Charlotte\", \n style: \"Meditation\", \n region: \"CA/Canadian\",\n fullName: \"Charlotte (Meditation) (English (CA)/Canadian)\"\n },\n { \n name: \"Cecil\", \n style: \"Conversational\", \n region: \"GB/British\",\n fullName: \"Cecil (English (GB)/British)\"\n },\n { \n name: \"Sterling\", \n style: \"Conversational\", \n region: \"GB/British\",\n fullName: \"Sterling (English (GB)/British)\"\n },\n { \n name: \"Cillian\", \n style: \"Conversational\", \n region: \"IE/Irish\",\n fullName: \"Cillian (English (IE)/Irish)\"\n },\n { \n name: \"Madison\", \n style: \"Conversational\", \n region: \"IE/Irish\",\n fullName: \"Madison (English (IE)/Irish)\"\n },\n { \n name: \"Ada\", \n style: \"Conversational\", \n region: \"ZA/South african\",\n fullName: \"Ada (English (ZA)/South african)\"\n },\n { \n name: \"Sumita\", \n style: \"Conversational\", \n region: \"IN/Indian\",\n fullName: \"Sumita (English (IN)/Indian)\"\n },\n { \n name: \"Navya\", \n style: \"Conversational\", \n region: \"IN/Indian\",\n fullName: \"Navya (English (IN)/Indian)\"\n }\n ],\n 'ja': [\n { \n name: \"Kiriko\", \n style: \"Conversational\", \n region: \"Japanese\",\n fullName: \"Kiriko Conversational (Japanese/Japanese)\"\n },\n { \n name: \"Kiriko\", \n style: \"Narrative\", \n region: \"Japanese\",\n fullName: \"Kiriko Narrative (Japanese/Japanese)\"\n }\n ],\n 'af': [\n { \n name: \"Ronel\", \n style: \"Conversational\", \n region: \"South african\",\n fullName: \"Ronel Conversational (Afrikaans/South african)\"\n },\n { \n name: \"Ronel\", \n style: \"Narrative\", \n region: \"South african\",\n fullName: \"Ronel Narrative (Afrikaans/South african)\"\n }\n ],\n 'ar': [\n { \n name: \"Abdo\", \n style: \"Conversational\", \n region: \"Arabic\",\n fullName: \"Abdo Conversational (Arabic/Arabic)\"\n },\n { \n name: \"Abdo\", \n style: \"Narrative\", \n region: \"Arabic\",\n fullName: \"Abdo Narrative (Arabic/Arabic)\"\n }\n ],\n 'bn': [\n { \n name: \"Mousmi\", \n style: \"Conversational\", \n region: \"Bengali\",\n fullName: \"Mousmi Conversational (Bengali/Bengali)\"\n },\n { \n name: \"Mousmi\", \n style: \"Narrative\", \n region: \"Bengali\",\n fullName: \"Mousmi Narrative (Bengali/Bengali)\"\n }\n ],\n 'pt': [\n { \n name: \"Caroline\", \n style: \"Conversational\", \n region: \"Brazilian\",\n fullName: \"Caroline Conversational (Portuguese (BR)/Brazilian)\"\n },\n { \n name: \"Caroline\", \n style: \"Narrative\", \n region: \"Brazilian\", \n fullName: \"Caroline Narrative (Portuguese (BR)/Brazilian)\"\n }\n ],\n 'fr': [\n { \n name: \"Ange\", \n style: \"Conversational\", \n region: \"French\",\n fullName: \"Ange Conversational (French/French)\"\n },\n { \n name: \"Ange\", \n style: \"Narrative\", \n region: \"French\",\n fullName: \"Ange Narrative (French/French)\"\n },\n { \n name: \"Baptiste\", \n style: \"Conversational\", \n region: \"French\",\n fullName: \"Baptiste (English (FR)/French)\"\n }\n ],\n 'de': [\n { \n name: \"Anke\", \n style: \"Conversational\", \n region: \"German\",\n fullName: \"Anke Conversational (German/German)\"\n },\n { \n name: \"Anke\", \n style: \"Narrative\", \n region: \"German\",\n fullName: \"Anke Narrative (German/German)\"\n }\n ],\n 'es': [\n { \n name: \"Carmen\", \n style: \"Conversational\", \n region: \"Spanish\",\n fullName: \"Carmen Conversational (Spanish/Spanish)\"\n },\n { \n name: \"Patricia\", \n style: \"Conversational\", \n region: \"Spanish\",\n fullName: \"Patricia Conversational (Spanish/Spanish)\"\n }\n ],\n 'ko': [\n { \n name: \"Dohee\", \n style: \"Conversational\", \n region: \"Korean\",\n fullName: \"Dohee Conversational (Korean/Korean)\"\n },\n { \n name: \"Dohee\", \n style: \"Narrative\", \n region: \"Korean\",\n fullName: \"Dohee Narrative (Korean/Korean)\"\n }\n ],\n 'he': [\n { \n name: \"Mary\", \n style: \"Conversational\", \n region: \"Israeli\",\n fullName: \"Mary Conversational (Hebrew/Israeli)\"\n },\n { \n name: \"Mary\", \n style: \"Narrative\", \n region: \"Israeli\",\n fullName: \"Mary Narrative (Hebrew/Israeli)\"\n }\n ],\n 'id': [\n { \n name: \"Ignatius\", \n style: \"Conversational\", \n region: \"Malay\",\n fullName: \"Ignatius Conversational (Malay/Malay)\"\n },\n { \n name: \"Ignatius\", \n style: \"Narrative\", \n region: \"Malay\",\n fullName: \"Ignatius Narrative (Malay/Malay)\"\n }\n ],\n 'ru': [\n { \n name: \"Andrei\", \n style: \"Conversational\", \n region: \"Russian\",\n fullName: \"Andrei Conversational (Russian/Russian)\"\n },\n { \n name: \"Andrei\", \n style: \"Narrative\", \n region: \"Russian\",\n fullName: \"Andrei Narrative (Russian/Russian)\"\n }\n ],\n 'tl': [\n { \n name: \"Aiken\", \n style: \"Conversational\", \n region: \"Filipino\",\n fullName: \"Aiken Conversational (Tagalog/Filipino)\"\n },\n { \n name: \"Aiken\", \n style: \"Narrative\", \n region: \"Filipino\",\n fullName: \"Aiken Narrative (Tagalog/Filipino)\"\n }\n ],\n 'mk': [\n { \n name: \"Aleksa\", \n style: \"Conversational\", \n region: \"Serbian\",\n fullName: \"Aleksa Conversational (Serbian/Serbian)\"\n },\n { \n name: \"Aleksa\", \n style: \"Narrative\", \n region: \"Serbian\",\n fullName: \"Aleksa Narrative (Serbian/Serbian)\"\n }\n ],\n 'ne': [\n { \n name: \"Anuj\", \n style: \"Conversational\", \n region: \"Indian\",\n fullName: \"Anuj Conversational (Hindi/Indian)\"\n },\n { \n name: \"Anuj\", \n style: \"Narrative\", \n region: \"Indian\",\n fullName: \"Anuj Narrative (Hindi/Indian)\"\n }\n ],\n 'th': [\n { \n name: \"Katbundit\", \n style: \"Conversational\", \n region: \"Thai\",\n fullName: \"Katbundit Conversational (Thai/Thai)\"\n },\n { \n name: \"Katbundit\", \n style: \"Narrative\", \n region: \"Thai\",\n fullName: \"Katbundit Narrative (Thai/Thai)\"\n }\n ],\n 'tr': [\n { \n name: \"Ali\", \n style: \"Conversational\", \n region: \"Turkish\",\n fullName: \"Ali Conversational (Turkish/Turkish)\"\n },\n { \n name: \"Ali\", \n style: \"Narrative\", \n region: \"Turkish\",\n fullName: \"Ali Narrative (Turkish/Turkish)\"\n }\n ],\n};\n\nexport const getRandomVoice = (voiceOptions: VoiceOption[]): VoiceOption => {\n const randomIndex = Math.floor(Math.random() * voiceOptions.length);\n return voiceOptions[randomIndex];\n };\n"],"mappings":"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","names":[]}
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/index.ts", "../src/directive-parser.ts", "../src/text-processor.ts", "../src/types.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Plugin TTS - Text-to-Speech coordinator for Eliza agents\n *\n * Provides a unified TTS interface that:\n * - Supports multiple providers (ElevenLabs, OpenAI, Edge, Simple Voice)\n * - Auto-selects providers based on available API keys\n * - Parses [[tts]] directives from messages\n * - Handles text processing and length limits\n * - Manages per-session TTS configuration\n */\n\nimport {\n type IAgentRuntime,\n ModelType,\n type Plugin,\n type Provider,\n type ProviderResult,\n logger,\n} from \"@elizaos/core\";\n\nimport {\n getTtsText,\n hasTtsDirective,\n parseTtsDirective,\n stripTtsDirectives,\n} from \"./directive-parser\";\nimport {\n cleanTextForTts,\n processTextForTts,\n truncateText,\n} from \"./text-processor\";\nimport {\n DEFAULT_TTS_CONFIG,\n TTS_PROVIDER_API_KEYS,\n TTS_PROVIDER_PRIORITY,\n type TtsApplyKind,\n type TtsAutoMode,\n type TtsConfig,\n type TtsDirective,\n type TtsProvider,\n type TtsRequest,\n type TtsResult,\n type TtsSessionConfig,\n} from \"./types\";\n\n// Re-export everything\nexport * from \"./types\";\nexport * from \"./directive-parser\";\nexport * from \"./text-processor\";\n\n// Session configurations\nconst sessionConfigs = new Map<string, TtsSessionConfig>();\n\n/**\n * Get TTS configuration for a session\n */\nexport function getTtsConfig(roomId: string): TtsConfig {\n const session = sessionConfigs.get(roomId);\n return {\n ...DEFAULT_TTS_CONFIG,\n ...session,\n };\n}\n\n/**\n * Set TTS configuration for a session\n */\nexport function setTtsConfig(\n roomId: string,\n config: Partial<TtsSessionConfig>,\n): void {\n const existing = sessionConfigs.get(roomId) ?? {};\n sessionConfigs.set(roomId, { ...existing, ...config });\n}\n\n/**\n * Clear TTS configuration for a session\n */\nexport function clearTtsConfig(roomId: string): void {\n sessionConfigs.delete(roomId);\n}\n\n/**\n * Check if a provider is available (has required API keys)\n */\nexport function isProviderAvailable(\n runtime: IAgentRuntime,\n provider: TtsProvider,\n): boolean {\n if (provider === \"auto\") return true;\n\n const requiredKeys = TTS_PROVIDER_API_KEYS[provider];\n if (requiredKeys.length === 0) {\n return true; // No API key required\n }\n\n return requiredKeys.some((key) => {\n const value = runtime.getSetting(key);\n return value && String(value).trim() !== \"\";\n });\n}\n\n/**\n * Get the best available provider\n */\nexport function getBestProvider(\n runtime: IAgentRuntime,\n preferred?: TtsProvider,\n): TtsProvider {\n // If preferred is specified and available, use it\n if (\n preferred &&\n preferred !== \"auto\" &&\n isProviderAvailable(runtime, preferred)\n ) {\n return preferred;\n }\n\n // Otherwise, find the first available provider in priority order\n for (const provider of TTS_PROVIDER_PRIORITY) {\n if (isProviderAvailable(runtime, provider)) {\n return provider;\n }\n }\n\n // Fallback to simple-voice (always available)\n return \"simple-voice\";\n}\n\n/**\n * Synthesize text to speech\n */\nexport async function synthesize(\n runtime: IAgentRuntime,\n request: TtsRequest,\n): Promise<TtsResult> {\n const provider = getBestProvider(runtime, request.provider);\n\n logger.debug(`[TTS] Synthesizing with provider: ${provider}`);\n\n const params = {\n text: request.text,\n voice: request.voice,\n model: request.model,\n speed: request.speed,\n provider, // Pass provider hint for routing\n };\n\n try {\n const audio = await runtime.useModel(ModelType.TEXT_TO_SPEECH, params);\n\n return {\n audio: Buffer.isBuffer(audio) ? audio : Buffer.from(audio as ArrayBuffer),\n format: request.format ?? \"mp3\",\n provider,\n };\n } catch (error) {\n logger.error(`[TTS] Synthesis failed with ${provider}: ${error}`);\n throw error;\n }\n}\n\n/**\n * Check if TTS should be applied to a reply\n */\nexport function shouldApplyTts(\n config: TtsConfig,\n options: {\n inboundAudio?: boolean;\n kind?: TtsApplyKind;\n hasDirective?: boolean;\n },\n): boolean {\n const { auto } = config;\n const { inboundAudio, kind, hasDirective } = options;\n\n // TTS is disabled\n if (auto === \"off\") {\n return false;\n }\n\n // Always apply TTS\n if (auto === \"always\") {\n return true;\n }\n\n // Only when inbound message had audio\n if (auto === \"inbound\") {\n return Boolean(inboundAudio);\n }\n\n // Only when [[tts]] directive is present\n if (auto === \"tagged\") {\n return Boolean(hasDirective);\n }\n\n return false;\n}\n\n/**\n * Apply TTS to a reply text if configured\n */\nexport async function maybeApplyTts(\n runtime: IAgentRuntime,\n roomId: string,\n text: string,\n options: {\n inboundAudio?: boolean;\n kind?: TtsApplyKind;\n },\n): Promise<Buffer | null> {\n const config = getTtsConfig(roomId);\n const directive = parseTtsDirective(text);\n const hasDirective = Boolean(directive);\n\n // Check if we should apply TTS\n if (!shouldApplyTts(config, { ...options, hasDirective })) {\n return null;\n }\n\n // Get the text to synthesize\n const ttsText = getTtsText(text, directive);\n\n // Process the text (clean, validate length, maybe summarize)\n const processed = await processTextForTts(runtime, ttsText, {\n maxLength: config.maxLength,\n summarize: config.summarize,\n });\n\n if (!processed) {\n logger.debug(\"[TTS] Text too short or invalid for TTS\");\n return null;\n }\n\n // Synthesize\n try {\n const result = await synthesize(runtime, {\n text: processed,\n provider: directive?.provider ?? config.provider,\n voice: directive?.voice ?? config.voice,\n model: directive?.model ?? config.model,\n speed: directive?.speed,\n });\n\n return result.audio;\n } catch (error) {\n logger.error(`[TTS] Failed to apply TTS: ${error}`);\n return null;\n }\n}\n\n/**\n * Format TTS configuration for display\n */\nexport function formatTtsConfig(config: TtsConfig): string {\n const lines: string[] = [];\n lines.push(`Auto: ${config.auto}`);\n lines.push(`Provider: ${config.provider}`);\n lines.push(`Max length: ${config.maxLength}`);\n lines.push(`Summarize: ${config.summarize ? \"yes\" : \"no\"}`);\n if (config.voice) {\n lines.push(`Voice: ${config.voice}`);\n }\n return lines.join(\"\\n\");\n}\n\n/**\n * Provider that exposes current TTS configuration\n */\nexport const ttsConfigProvider: Provider = {\n name: \"TTS_CONFIG\",\n description: \"Current text-to-speech configuration\",\n dynamic: true,\n\n async get(runtime, message, _state): Promise<ProviderResult> {\n const config = getTtsConfig(message.roomId);\n const bestProvider = getBestProvider(runtime, config.provider);\n\n return {\n text: formatTtsConfig(config),\n values: {\n ttsAuto: config.auto,\n ttsProvider: config.provider,\n ttsActiveProvider: bestProvider,\n ttsMaxLength: config.maxLength,\n ttsSummarize: config.summarize,\n ttsVoice: config.voice ?? \"\",\n },\n data: { config },\n };\n },\n};\n\n/**\n * Plugin TTS\n *\n * Coordinates text-to-speech synthesis across multiple providers.\n * Works with existing TTS plugins (plugin-edge-tts, plugin-elevenlabs, etc.)\n * to provide a unified interface.\n */\nexport const ttsPlugin: Plugin = {\n name: \"tts\",\n description:\n \"Text-to-speech coordinator with multi-provider support and [[tts]] directives\",\n\n providers: [ttsConfigProvider],\n\n config: {\n TTS_AUTO_MODE: \"off\",\n TTS_DEFAULT_PROVIDER: \"auto\",\n TTS_MAX_LENGTH: \"1500\",\n TTS_SUMMARIZE: \"true\",\n TTS_DEFAULT_VOICE: \"\",\n },\n\n tests: [\n {\n name: \"tts-directives\",\n tests: [\n {\n name: \"Detect TTS directive\",\n fn: async (_runtime: IAgentRuntime) => {\n if (!hasTtsDirective(\"Hello [[tts]] world\")) {\n throw new Error(\"Should detect [[tts]] directive\");\n }\n if (!hasTtsDirective(\"[[tts:provider=elevenlabs]] Hello\")) {\n throw new Error(\"Should detect [[tts:provider=...]] directive\");\n }\n if (!hasTtsDirective(\"[[tts:text]]Hello[[/tts:text]]\")) {\n throw new Error(\"Should detect [[tts:text]] directive\");\n }\n if (hasTtsDirective(\"No directive here\")) {\n throw new Error(\"Should not detect directive in plain text\");\n }\n logger.success(\"TTS directive detection works correctly\");\n },\n },\n {\n name: \"Parse TTS directive with options\",\n fn: async (_runtime: IAgentRuntime) => {\n const directive = parseTtsDirective(\n \"[[tts:provider=elevenlabs voice=alloy speed=1.5]] Hello\",\n );\n if (!directive) {\n throw new Error(\"Should parse directive\");\n }\n if (directive.provider !== \"elevenlabs\") {\n throw new Error(\n `Expected provider 'elevenlabs', got '${directive.provider}'`,\n );\n }\n if (directive.voice !== \"alloy\") {\n throw new Error(\n `Expected voice 'alloy', got '${directive.voice}'`,\n );\n }\n if (directive.speed !== 1.5) {\n throw new Error(`Expected speed 1.5, got ${directive.speed}`);\n }\n logger.success(\"TTS directive parsing works correctly\");\n },\n },\n {\n name: \"Parse TTS text block\",\n fn: async (_runtime: IAgentRuntime) => {\n const directive = parseTtsDirective(\n \"Some text [[tts:text]]This is the TTS text[[/tts:text]] more text\",\n );\n if (!directive) {\n throw new Error(\"Should parse directive\");\n }\n if (directive.text !== \"This is the TTS text\") {\n throw new Error(\n `Expected text 'This is the TTS text', got '${directive.text}'`,\n );\n }\n logger.success(\"TTS text block parsing works correctly\");\n },\n },\n {\n name: \"Strip TTS directives\",\n fn: async (_runtime: IAgentRuntime) => {\n const text =\n \"Hello [[tts:provider=elevenlabs]] world [[tts:text]]TTS text[[/tts:text]]\";\n const stripped = stripTtsDirectives(text);\n if (stripped !== \"Hello world\") {\n throw new Error(`Expected 'Hello world', got '${stripped}'`);\n }\n logger.success(\"TTS directive stripping works correctly\");\n },\n },\n {\n name: \"Get TTS text with directive\",\n fn: async (_runtime: IAgentRuntime) => {\n const text = \"Message [[tts:text]]Custom TTS[[/tts:text]]\";\n const directive = parseTtsDirective(text);\n const ttsText = getTtsText(text, directive);\n if (ttsText !== \"Custom TTS\") {\n throw new Error(`Expected 'Custom TTS', got '${ttsText}'`);\n }\n logger.success(\"TTS text extraction works correctly\");\n },\n },\n {\n name: \"Get TTS text without directive\",\n fn: async (_runtime: IAgentRuntime) => {\n const text = \"Plain message\";\n const directive = parseTtsDirective(text);\n const ttsText = getTtsText(text, directive);\n if (ttsText !== \"Plain message\") {\n throw new Error(`Expected 'Plain message', got '${ttsText}'`);\n }\n logger.success(\"TTS text fallback works correctly\");\n },\n },\n ],\n },\n {\n name: \"tts-text-processing\",\n tests: [\n {\n name: \"Clean text for TTS\",\n fn: async (_runtime: IAgentRuntime) => {\n const text = \"**Bold** and `code` with https://example.com\";\n const cleaned = cleanTextForTts(text);\n if (cleaned !== \"Bold and [code] with [link]\") {\n throw new Error(`Expected clean text, got '${cleaned}'`);\n }\n logger.success(\"Text cleaning works correctly\");\n },\n },\n {\n name: \"Truncate text\",\n fn: async (_runtime: IAgentRuntime) => {\n const text =\n \"This is a long sentence. Another sentence here. And more text.\";\n const truncated = truncateText(text, 40);\n if (truncated.length > 43) {\n // +3 for \"...\"\n throw new Error(\n `Expected truncated text, got length ${truncated.length}`,\n );\n }\n logger.success(\"Text truncation works correctly\");\n },\n },\n ],\n },\n {\n name: \"tts-config\",\n tests: [\n {\n name: \"Session config management\",\n fn: async (_runtime: IAgentRuntime) => {\n const roomId = \"test-room-tts\";\n clearTtsConfig(roomId);\n\n setTtsConfig(roomId, { auto: \"always\", provider: \"edge\" });\n\n const config = getTtsConfig(roomId);\n if (config.auto !== \"always\") {\n throw new Error(`Expected auto 'always', got '${config.auto}'`);\n }\n if (config.provider !== \"edge\") {\n throw new Error(\n `Expected provider 'edge', got '${config.provider}'`,\n );\n }\n\n clearTtsConfig(roomId);\n logger.success(\"TTS config management works correctly\");\n },\n },\n {\n name: \"Should apply TTS logic\",\n fn: async (_runtime: IAgentRuntime) => {\n // Off mode\n if (shouldApplyTts({ ...DEFAULT_TTS_CONFIG, auto: \"off\" }, {})) {\n throw new Error(\"Should not apply when auto is off\");\n }\n\n // Always mode\n if (\n !shouldApplyTts({ ...DEFAULT_TTS_CONFIG, auto: \"always\" }, {})\n ) {\n throw new Error(\"Should apply when auto is always\");\n }\n\n // Inbound mode\n if (\n shouldApplyTts({ ...DEFAULT_TTS_CONFIG, auto: \"inbound\" }, {})\n ) {\n throw new Error(\"Should not apply when inbound without audio\");\n }\n if (\n !shouldApplyTts(\n { ...DEFAULT_TTS_CONFIG, auto: \"inbound\" },\n { inboundAudio: true },\n )\n ) {\n throw new Error(\"Should apply when inbound with audio\");\n }\n\n // Tagged mode\n if (shouldApplyTts({ ...DEFAULT_TTS_CONFIG, auto: \"tagged\" }, {})) {\n throw new Error(\"Should not apply when tagged without directive\");\n }\n if (\n !shouldApplyTts(\n { ...DEFAULT_TTS_CONFIG, auto: \"tagged\" },\n { hasDirective: true },\n )\n ) {\n throw new Error(\"Should apply when tagged with directive\");\n }\n\n logger.success(\"TTS apply logic works correctly\");\n },\n },\n ],\n },\n ],\n\n async init(config, runtime) {\n logger.log(\"[plugin-tts] Initializing TTS coordinator\");\n\n const autoMode = (config.TTS_AUTO_MODE as TtsAutoMode) ?? \"off\";\n const provider = (config.TTS_DEFAULT_PROVIDER as TtsProvider) ?? \"auto\";\n\n logger.log(\n `[plugin-tts] Auto mode: ${autoMode}, Default provider: ${provider}`,\n );\n\n // Log available providers\n const available = TTS_PROVIDER_PRIORITY.filter((p) =>\n isProviderAvailable(runtime, p),\n );\n logger.log(\n `[plugin-tts] Available providers: ${available.join(\", \") || \"none\"}`,\n );\n },\n};\n\nexport default ttsPlugin;\n",
6
+ "/**\n * TTS directive parser\n *\n * Parses [[tts]] directives from text:\n * - [[tts]] - Simple marker to enable TTS for this message\n * - [[tts:provider=elevenlabs]] - Specify provider\n * - [[tts:voice=alloy]] - Specify voice\n * - [[tts:text]]...[[/tts:text]] - Specify exact text to synthesize\n */\n\nimport type { TtsDirective, TtsProvider } from \"./types\";\n\n// Regex patterns\nconst TTS_DIRECTIVE_PATTERN = /\\[\\[tts(?::([^\\]]+))?\\]\\]/gi;\nconst TTS_TEXT_PATTERN = /\\[\\[tts:text\\]\\]([\\s\\S]*?)\\[\\[\\/tts:text\\]\\]/gi;\nconst KEY_VALUE_PATTERN = /(\\w+)\\s*=\\s*([^\\s,]+)/g;\n\n/**\n * Check if text contains any TTS directive\n */\nexport function hasTtsDirective(text: string): boolean {\n return TTS_DIRECTIVE_PATTERN.test(text) || TTS_TEXT_PATTERN.test(text);\n}\n\n/**\n * Parse TTS directives from text\n */\nexport function parseTtsDirective(text: string): TtsDirective | null {\n if (!hasTtsDirective(text)) {\n return null;\n }\n\n const directive: TtsDirective = {};\n\n // Extract [[tts:text]]...[[/tts:text]] content\n const textMatch = text.match(TTS_TEXT_PATTERN);\n if (textMatch) {\n // Get the content between tags\n const fullMatch = textMatch[0];\n const contentStart = fullMatch.indexOf(\"]]\") + 2;\n const contentEnd = fullMatch.lastIndexOf(\"[[\");\n directive.text = fullMatch.slice(contentStart, contentEnd).trim();\n }\n\n // Parse [[tts:key=value]] directives\n TTS_DIRECTIVE_PATTERN.lastIndex = 0;\n let match;\n while ((match = TTS_DIRECTIVE_PATTERN.exec(text)) !== null) {\n const params = match[1];\n if (params) {\n let kvMatch;\n KEY_VALUE_PATTERN.lastIndex = 0;\n while ((kvMatch = KEY_VALUE_PATTERN.exec(params)) !== null) {\n const key = kvMatch[1].toLowerCase();\n const value = kvMatch[2];\n\n switch (key) {\n case \"provider\":\n directive.provider = normalizeProvider(value);\n break;\n case \"voice\":\n directive.voice = value;\n break;\n case \"model\":\n directive.model = value;\n break;\n case \"speed\":\n directive.speed = parseFloat(value);\n break;\n }\n }\n }\n }\n\n return directive;\n}\n\n/**\n * Normalize provider name\n */\nfunction normalizeProvider(raw: string): TtsProvider | undefined {\n const normalized = raw.toLowerCase().trim();\n switch (normalized) {\n case \"elevenlabs\":\n case \"eleven\":\n case \"xi\":\n return \"elevenlabs\";\n case \"openai\":\n case \"oai\":\n return \"openai\";\n case \"edge\":\n case \"microsoft\":\n case \"ms\":\n return \"edge\";\n case \"simple\":\n case \"simple-voice\":\n case \"sam\":\n return \"simple-voice\";\n default:\n return undefined;\n }\n}\n\n/**\n * Strip TTS directives from text\n */\nexport function stripTtsDirectives(text: string): string {\n let cleaned = text;\n\n // Remove [[tts:text]]...[[/tts:text]] blocks\n cleaned = cleaned.replace(TTS_TEXT_PATTERN, \"\");\n\n // Remove [[tts:...]] directives\n cleaned = cleaned.replace(TTS_DIRECTIVE_PATTERN, \"\");\n\n // Clean up extra whitespace\n return cleaned.replace(/\\s+/g, \" \").trim();\n}\n\n/**\n * Get text to synthesize from message\n * Returns directive text if specified, otherwise the full cleaned text\n */\nexport function getTtsText(\n text: string,\n directive: TtsDirective | null,\n): string {\n if (directive?.text) {\n return directive.text;\n }\n return stripTtsDirectives(text);\n}\n",
7
+ "/**\n * Text processor for TTS\n *\n * Handles text cleaning, length limits, and summarization\n */\n\nimport type { IAgentRuntime } from \"@elizaos/core\";\n\n/**\n * Clean text for TTS synthesis\n * Removes markdown, code blocks, and other non-speech content\n */\nexport function cleanTextForTts(text: string): string {\n let cleaned = text;\n\n // Remove code blocks\n cleaned = cleaned.replace(/```[\\s\\S]*?```/g, \"[code block]\");\n\n // Remove inline code\n cleaned = cleaned.replace(/`[^`]+`/g, \"[code]\");\n\n // Remove URLs\n cleaned = cleaned.replace(/https?:\\/\\/[^\\s]+/g, \"[link]\");\n\n // Remove markdown bold/italic\n cleaned = cleaned.replace(/\\*\\*([^*]+)\\*\\*/g, \"$1\");\n cleaned = cleaned.replace(/\\*([^*]+)\\*/g, \"$1\");\n cleaned = cleaned.replace(/__([^_]+)__/g, \"$1\");\n cleaned = cleaned.replace(/_([^_]+)_/g, \"$1\");\n\n // Remove markdown headers\n cleaned = cleaned.replace(/^#{1,6}\\s+/gm, \"\");\n\n // Remove markdown links but keep text\n cleaned = cleaned.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, \"$1\");\n\n // Remove HTML tags\n cleaned = cleaned.replace(/<[^>]+>/g, \"\");\n\n // Convert multiple newlines to single\n cleaned = cleaned.replace(/\\n{2,}/g, \"\\n\");\n\n // Remove leading/trailing whitespace\n cleaned = cleaned.trim();\n\n return cleaned;\n}\n\n/**\n * Truncate text to max length, trying to break at sentence boundaries\n */\nexport function truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n\n // Try to break at sentence boundary\n const truncated = text.slice(0, maxLength);\n const lastSentenceEnd = Math.max(\n truncated.lastIndexOf(\". \"),\n truncated.lastIndexOf(\"! \"),\n truncated.lastIndexOf(\"? \"),\n truncated.lastIndexOf(\".\\n\"),\n truncated.lastIndexOf(\"!\\n\"),\n truncated.lastIndexOf(\"?\\n\"),\n );\n\n if (lastSentenceEnd > maxLength * 0.5) {\n return truncated.slice(0, lastSentenceEnd + 1).trim();\n }\n\n // Fall back to word boundary\n const lastSpace = truncated.lastIndexOf(\" \");\n if (lastSpace > maxLength * 0.8) {\n return truncated.slice(0, lastSpace).trim() + \"...\";\n }\n\n return truncated.trim() + \"...\";\n}\n\n/**\n * Summarize text using LLM for TTS\n */\nexport async function summarizeForTts(\n runtime: IAgentRuntime,\n text: string,\n maxLength: number,\n): Promise<string> {\n try {\n const prompt = `Summarize the following text in ${maxLength} characters or less for text-to-speech. Keep the key points and maintain a conversational tone:\\n\\n${text}`;\n\n const response = await runtime.useModel(\"TEXT_SMALL\", {\n prompt,\n maxTokens: Math.ceil(maxLength / 3), // Rough estimate\n });\n\n if (typeof response === \"string\") {\n return response.slice(0, maxLength);\n }\n\n // Fallback to truncation\n return truncateText(text, maxLength);\n } catch {\n // Fallback to truncation on error\n return truncateText(text, maxLength);\n }\n}\n\n/**\n * Process text for TTS synthesis\n * Cleans, validates length, and optionally summarizes\n */\nexport async function processTextForTts(\n runtime: IAgentRuntime,\n text: string,\n options: {\n maxLength: number;\n summarize: boolean;\n minLength?: number;\n },\n): Promise<string | null> {\n const { maxLength, summarize, minLength = 10 } = options;\n\n // Clean the text\n let processed = cleanTextForTts(text);\n\n // Check minimum length\n if (processed.length < minLength) {\n return null;\n }\n\n // Check maximum length\n if (processed.length > maxLength) {\n if (summarize) {\n processed = await summarizeForTts(runtime, processed, maxLength);\n } else {\n processed = truncateText(processed, maxLength);\n }\n }\n\n return processed;\n}\n",
8
+ "/**\n * TTS system types\n */\n\nexport type TtsProvider =\n | \"elevenlabs\"\n | \"openai\"\n | \"edge\"\n | \"simple-voice\"\n | \"auto\";\nexport type TtsAutoMode = \"off\" | \"always\" | \"inbound\" | \"tagged\";\nexport type TtsApplyKind = \"tool\" | \"block\" | \"final\";\n\nexport interface TtsConfig {\n provider: TtsProvider;\n auto: TtsAutoMode;\n maxLength: number;\n summarize: boolean;\n voice?: string;\n model?: string;\n speed?: number;\n}\n\nexport interface TtsDirective {\n provider?: TtsProvider;\n voice?: string;\n model?: string;\n speed?: number;\n text?: string; // [[tts:text]]...[[/tts:text]] extracted content\n}\n\nexport interface TtsRequest {\n text: string;\n provider?: TtsProvider;\n voice?: string;\n model?: string;\n speed?: number;\n format?: \"mp3\" | \"opus\" | \"wav\";\n}\n\nexport interface TtsResult {\n audio: Buffer;\n format: string;\n duration?: number;\n provider: TtsProvider;\n}\n\nexport interface TtsSessionConfig {\n auto?: TtsAutoMode;\n provider?: TtsProvider;\n voice?: string;\n maxLength?: number;\n summarize?: boolean;\n}\n\nexport const DEFAULT_TTS_CONFIG: TtsConfig = {\n provider: \"auto\",\n auto: \"off\",\n maxLength: 1500,\n summarize: true,\n};\n\n// Provider priority for auto-selection\nexport const TTS_PROVIDER_PRIORITY: TtsProvider[] = [\n \"elevenlabs\",\n \"openai\",\n \"edge\",\n \"simple-voice\",\n];\n\n// API key environment variable names for each provider\nexport const TTS_PROVIDER_API_KEYS: Record<TtsProvider, string[]> = {\n elevenlabs: [\"ELEVENLABS_API_KEY\", \"XI_API_KEY\"],\n openai: [\"OPENAI_API_KEY\"],\n edge: [], // No API key required\n \"simple-voice\": [], // No API key required\n auto: [], // Not applicable\n};\n"
9
+ ],
10
+ "mappings": "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",
11
+ "debugId": "554A80245C4B812D64756E2164756E21",
12
+ "names": []
13
+ }
package/package.json CHANGED
@@ -1,35 +1,95 @@
1
1
  {
2
- "name": "@elizaos/plugin-tts",
3
- "version": "0.1.9",
4
- "type": "module",
5
- "main": "dist/index.js",
6
- "module": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- "./package.json": "./package.json",
10
- ".": {
11
- "import": {
12
- "@elizaos/source": "./src/index.ts",
13
- "types": "./dist/index.d.ts",
14
- "default": "./dist/index.js"
15
- }
16
- }
17
- },
18
- "files": [
19
- "dist"
20
- ],
21
- "dependencies": {
22
- "@elizaos/core": "0.1.9",
23
- "langdetect": "0.2.1",
24
- "tsup": "8.3.5",
25
- "whatwg-url": "7.1.0"
26
- },
27
- "scripts": {
28
- "build": "tsup --format esm --dts",
29
- "dev": "tsup --format esm --dts --watch"
30
- },
31
- "peerDependencies": {
32
- "whatwg-url": "7.1.0"
33
- },
34
- "gitHead": "ffa4c1dcdacc096d5b451f246b53fbaa266b0f64"
2
+ "name": "@elizaos/plugin-tts",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "main": "dist/cjs/index.cjs",
6
+ "module": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "sideEffects": false,
9
+ "description": "Text-to-speech coordinator for Eliza agents with multi-provider support",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/elizaos/eliza.git"
13
+ },
14
+ "exports": {
15
+ "./package.json": "./package.json",
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/cjs/index.cjs",
20
+ "default": "./dist/index.js"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "dependencies": {
27
+ "@elizaos/core": "workspace:*"
28
+ },
29
+ "devDependencies": {
30
+ "@types/bun": "^1.2.22",
31
+ "@types/node": "^24.5.2",
32
+ "prettier": "3.6.2",
33
+ "typescript": "^5.9.2"
34
+ },
35
+ "scripts": {
36
+ "build": "bun run build.ts",
37
+ "dev": "bun --hot build.ts",
38
+ "test": "elizaos test",
39
+ "clean": "rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo",
40
+ "format": "prettier --write ./src",
41
+ "format:check": "prettier --check ./src",
42
+ "lint": "prettier --write ./src"
43
+ },
44
+ "publishConfig": {
45
+ "access": "public"
46
+ },
47
+ "agentConfig": {
48
+ "pluginType": "elizaos:plugin:1.0.0",
49
+ "pluginParameters": {
50
+ "TTS_AUTO_MODE": {
51
+ "type": "string",
52
+ "description": "When to automatically apply TTS (off, always, inbound, tagged)",
53
+ "required": false,
54
+ "default": "off",
55
+ "sensitive": false
56
+ },
57
+ "TTS_DEFAULT_PROVIDER": {
58
+ "type": "string",
59
+ "description": "Default TTS provider (auto, elevenlabs, openai, edge, simple-voice)",
60
+ "required": false,
61
+ "default": "auto",
62
+ "sensitive": false
63
+ },
64
+ "TTS_MAX_LENGTH": {
65
+ "type": "number",
66
+ "description": "Maximum text length for TTS synthesis",
67
+ "required": false,
68
+ "default": "1500",
69
+ "sensitive": false
70
+ },
71
+ "TTS_SUMMARIZE": {
72
+ "type": "boolean",
73
+ "description": "Summarize long text instead of truncating",
74
+ "required": false,
75
+ "default": "true",
76
+ "sensitive": false
77
+ },
78
+ "TTS_DEFAULT_VOICE": {
79
+ "type": "string",
80
+ "description": "Default voice ID for synthesis",
81
+ "required": false,
82
+ "sensitive": false
83
+ }
84
+ }
85
+ },
86
+ "milaidy": {
87
+ "platforms": [
88
+ "node"
89
+ ],
90
+ "runtime": "node",
91
+ "platformDetails": {
92
+ "node": "Default export (Node.js)"
93
+ }
94
+ }
35
95
  }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Shaw Walters, aka Moon aka @lalalune
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/README.md DELETED
@@ -1,173 +0,0 @@
1
- # @elizaos/plugin-tts
2
-
3
- A plugin for text-to-speech(TTS) generation using the FAL.ai API within the ElizaOS ecosystem.
4
-
5
- ## Description
6
-
7
- The text-to-speech(TTS) plugin enables AI-powered creation of speech through FAL.ai's services. It provides functionality to generate audio from text descriptions, automatically detects language, and selects appropriate voice models.
8
-
9
- ## Installation
10
-
11
- ```bash
12
- pnpm install @elizaos/plugin-tts
13
- ```
14
-
15
- ## Configuration
16
-
17
- The plugin requires the following environment variable or runtime setting to be set:
18
-
19
- ```typescript
20
- FAL_API_KEY=<Your FAL.ai API key>
21
- ```
22
-
23
- ## Usage
24
-
25
- ### Basic Integration
26
-
27
- ```typescript
28
- import { TTSGenerationPlugin } from "@elizaos/plugin-tts";
29
- ```
30
-
31
- ### Voice Generation Examples
32
-
33
- ```typescript
34
- // The plugin responds to natural language commands like:
35
-
36
- "Generate TTS of Hello World";
37
- "Create a TTS for Welcome to ElizaOS";
38
- "Make a TTS saying [your text]";
39
- ```
40
-
41
- ## API Reference
42
-
43
- ### Actions
44
-
45
- #### GENERATE_TTS
46
-
47
- Generates speech audio based on text input.
48
-
49
- **Aliases:**
50
- - TTS_GENERATION
51
- - CREATE_TTS
52
- - TEXT2SPEECH
53
- - T2S
54
- - TEXT_TO_SPEECH
55
- - AUDIO_CREATE
56
-
57
- **Features:**
58
- - Automatic language detection
59
- - Voice selection based on detected language
60
- - Local file caching
61
- - Progress tracking
62
- - Error handling
63
-
64
- ## Common Issues & Troubleshooting
65
-
66
- 1. **Generation Failures**
67
- - Verify FAL API key is correctly set
68
- - Ensure text input is at least 3 characters long
69
- - Check network connectivity to FAL.ai services
70
-
71
- 2. **Storage Issues**
72
- - Verify write permissions to content_cache directory
73
- - Ensure sufficient disk space
74
- - Check if content_cache directory exists
75
-
76
- ## Security Best Practices
77
-
78
- 1. **API Key Management**
79
- - Store FAL API key securely using runtime settings or environment variables
80
- - Never commit API keys to version control
81
- - Monitor API usage
82
-
83
- ## Development Guide
84
-
85
- ### Setting Up Development Environment
86
-
87
- 1. Clone the repository
88
- 2. Install dependencies:
89
-
90
- ```bash
91
- pnpm install
92
- ```
93
-
94
- 3. Build the plugin:
95
-
96
- ```bash
97
- pnpm run build
98
- ```
99
-
100
- 4. Run the plugin:
101
-
102
- ```bash
103
- pnpm run dev
104
- ```
105
-
106
- ## Future Enhancements
107
-
108
- 1. **Advanced Voice Features**
109
- - Custom voice model support
110
- - Voice style transfer
111
- - Emotion control
112
- - Speech rate adjustment
113
- - Pitch modification
114
- - Multiple speaker support
115
-
116
- 2. **Audio Processing**
117
- - Background noise reduction
118
- - Audio quality enhancement
119
- - Format conversion options
120
- - Volume normalization
121
- - Audio effects processing
122
- - Batch processing support
123
-
124
- 3. **Language Support**
125
- - Expanded language detection
126
- - Regional accent support
127
- - Dialect customization
128
- - Pronunciation improvements
129
- - Multi-language mixing
130
- - Custom pronunciation rules
131
-
132
- 4. **Integration Features**
133
- - Streaming audio support
134
- - Real-time generation
135
- - Caching optimization
136
- - Batch generation
137
- - Queue management
138
- - Progress monitoring
139
-
140
- 5. **Developer Tools**
141
- - Extended API options
142
- - Testing framework
143
- - Performance profiling
144
- - Debug logging
145
- - Integration examples
146
- - Documentation generator
147
-
148
- We welcome community feedback and contributions to help prioritize these enhancements.
149
-
150
- ## Contributing
151
-
152
- Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
153
-
154
- ## Credits
155
-
156
- This plugin integrates with and builds upon several key technologies:
157
-
158
- - [FAL.ai](https://fal.ai/): AI model deployment platform
159
- - [langdetect](https://github.com/wooorm/franc): Language detection library
160
- - [ElizaOS](https://elizaos.com): Core framework
161
-
162
- Special thanks to:
163
- - The FAL.ai team for AI infrastructure
164
- - The langdetect development community
165
- - The Eliza community for their contributions and feedback
166
-
167
- For more information about TTS capabilities:
168
- - [FAL.ai Documentation](https://fal.ai/docs)
169
- - [ElizaOS Documentation](https://elizaos.github.io/eliza/)
170
-
171
- ## License
172
-
173
- This plugin is part of the Eliza project. See the main project repository for license information.
package/dist/index.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import { Plugin } from '@elizaos/core';
2
-
3
- declare const TTSGenerationPlugin: Plugin;
4
-
5
- export { TTSGenerationPlugin };