@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/cjs/index.cjs +560 -0
- package/dist/cjs/index.cjs.map +13 -0
- package/dist/index.js +509 -454
- package/dist/index.js.map +13 -1
- package/package.json +93 -33
- package/LICENSE +0 -21
- package/README.md +0 -173
- package/dist/index.d.ts +0 -5
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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.
|