@elizaos/plugin-tts 2.0.0-alpha.3 → 2.0.0-alpha.5

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.
@@ -39,6 +39,7 @@ __export(exports_src, {
39
39
  setTtsConfig: () => setTtsConfig,
40
40
  processTextForTts: () => processTextForTts,
41
41
  parseTtsDirective: () => parseTtsDirective,
42
+ parseJsonVoiceDirective: () => parseJsonVoiceDirective,
42
43
  maybeApplyTts: () => maybeApplyTts,
43
44
  isProviderAvailable: () => isProviderAvailable,
44
45
  hasTtsDirective: () => hasTtsDirective,
@@ -126,6 +127,45 @@ function normalizeProvider(raw) {
126
127
  return;
127
128
  }
128
129
  }
130
+ function parseJsonVoiceDirective(text) {
131
+ const firstNewline = text.indexOf(`
132
+ `);
133
+ if (firstNewline === -1)
134
+ return null;
135
+ const firstLine = text.slice(0, firstNewline).trim();
136
+ if (!firstLine.startsWith("{") || !firstLine.endsWith("}"))
137
+ return null;
138
+ try {
139
+ const obj = JSON.parse(firstLine);
140
+ const voiceKeys = [
141
+ "voice",
142
+ "voice_id",
143
+ "voiceId",
144
+ "model",
145
+ "model_id",
146
+ "modelId",
147
+ "speed",
148
+ "rate"
149
+ ];
150
+ const hasVoiceKey = voiceKeys.some((k) => (k in obj));
151
+ if (!hasVoiceKey)
152
+ return null;
153
+ const directive = {};
154
+ const voice = obj.voice ?? obj.voice_id ?? obj.voiceId;
155
+ if (typeof voice === "string")
156
+ directive.voice = voice;
157
+ const model = obj.model ?? obj.model_id ?? obj.modelId;
158
+ if (typeof model === "string")
159
+ directive.model = model;
160
+ const speed = typeof obj.speed === "number" ? obj.speed : typeof obj.rate === "number" ? obj.rate : undefined;
161
+ if (speed !== undefined)
162
+ directive.speed = speed;
163
+ const cleanedText = text.slice(firstNewline + 1).trim();
164
+ return { directive, cleanedText };
165
+ } catch {
166
+ return null;
167
+ }
168
+ }
129
169
  function stripTtsDirectives(text) {
130
170
  let cleaned = text;
131
171
  cleaned = cleaned.replace(TTS_TEXT_PATTERN, "");
@@ -374,6 +414,49 @@ var ttsPlugin = {
374
414
  name: "tts",
375
415
  description: "Text-to-speech coordinator with multi-provider support and [[tts]] directives",
376
416
  providers: [ttsConfigProvider],
417
+ events: {
418
+ [import_core.EventType.HOOK_MESSAGE_SENDING]: [
419
+ async (payload) => {
420
+ if (!payload.runtime || !payload.content || payload.cancel)
421
+ return;
422
+ const runtime = payload.runtime;
423
+ const roomId = payload.to ?? "";
424
+ const config = getTtsConfig(roomId);
425
+ const jsonDirective = parseJsonVoiceDirective(payload.content);
426
+ const tagDirective = parseTtsDirective(payload.content);
427
+ const hasDirective = Boolean(jsonDirective || tagDirective);
428
+ const inboundAudio = Boolean(payload.metadata && "inboundAudio" in payload.metadata && payload.metadata.inboundAudio);
429
+ if (!shouldApplyTts(config, { inboundAudio, hasDirective })) {
430
+ return;
431
+ }
432
+ const directive = jsonDirective?.directive ?? tagDirective;
433
+ const textToSpeak = jsonDirective ? jsonDirective.cleanedText : getTtsText(payload.content, tagDirective);
434
+ if (!textToSpeak.trim())
435
+ return;
436
+ try {
437
+ const result = await synthesize(runtime, {
438
+ text: textToSpeak,
439
+ provider: directive?.provider ?? config.provider,
440
+ voice: directive?.voice ?? config.voice,
441
+ model: directive?.model ?? config.model,
442
+ speed: directive?.speed
443
+ });
444
+ payload.metadata = {
445
+ ...payload.metadata,
446
+ ttsAudio: result.audio,
447
+ ttsFormat: result.format,
448
+ ttsProvider: result.provider
449
+ };
450
+ if (jsonDirective) {
451
+ payload.content = jsonDirective.cleanedText;
452
+ }
453
+ import_core.logger.debug(`[TTS] Generated ${result.format} audio via ${result.provider} for room ${roomId}`);
454
+ } catch (err) {
455
+ import_core.logger.warn(`[TTS] Failed to generate speech: ${err instanceof Error ? err.message : String(err)}`);
456
+ }
457
+ }
458
+ ]
459
+ },
377
460
  config: {
378
461
  TTS_AUTO_MODE: "off",
379
462
  TTS_DEFAULT_PROVIDER: "auto",
@@ -557,4 +640,4 @@ var ttsPlugin = {
557
640
  };
558
641
  var src_default = ttsPlugin;
559
642
 
560
- //# debugId=049CD93507972CAC64756E2164756E21
643
+ //# debugId=3D14662809B323CC64756E2164756E21
@@ -2,12 +2,12 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.ts", "../../src/directive-parser.ts", "../../src/text-processor.ts", "../../src/types.ts"],
4
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",
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 EventType,\n type HookMessageSendingPayload,\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 parseJsonVoiceDirective,\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 events: {\n [EventType.HOOK_MESSAGE_SENDING]: [\n async (payload: HookMessageSendingPayload) => {\n if (!payload.runtime || !payload.content || payload.cancel) return;\n\n const runtime = payload.runtime;\n const roomId = payload.to ?? \"\";\n const config = getTtsConfig(roomId);\n\n // Check JSON voice directive (openclaw-classic format)\n const jsonDirective = parseJsonVoiceDirective(payload.content);\n\n // Check [[tts]] directive\n const tagDirective = parseTtsDirective(payload.content);\n const hasDirective = Boolean(jsonDirective || tagDirective);\n\n const inboundAudio = Boolean(\n payload.metadata &&\n \"inboundAudio\" in payload.metadata &&\n payload.metadata.inboundAudio,\n );\n\n if (!shouldApplyTts(config, { inboundAudio, hasDirective })) {\n return;\n }\n\n // Determine text to synthesize and any directive overrides\n const directive = jsonDirective?.directive ?? tagDirective;\n const textToSpeak = jsonDirective\n ? jsonDirective.cleanedText\n : getTtsText(payload.content, tagDirective);\n\n if (!textToSpeak.trim()) return;\n\n try {\n const result = await synthesize(runtime, {\n text: textToSpeak,\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 // Attach TTS audio to message metadata for the channel to send\n payload.metadata = {\n ...payload.metadata,\n ttsAudio: result.audio,\n ttsFormat: result.format,\n ttsProvider: result.provider,\n };\n\n // If we parsed a JSON voice directive, replace the content with cleaned text\n if (jsonDirective) {\n payload.content = jsonDirective.cleanedText;\n }\n\n logger.debug(\n `[TTS] Generated ${result.format} audio via ${result.provider} for room ${roomId}`,\n );\n } catch (err) {\n logger.warn(\n `[TTS] Failed to generate speech: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n },\n ],\n },\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 * Parse a JSON voice directive from the first line of the reply.\n *\n * openclaw-classic format:\n * { \"voice\": \"abc123\", \"once\": true }\n * Actual reply text here...\n *\n * Supported keys: voice/voice_id/voiceId, model/model_id/modelId,\n * speed, rate, stability, similarity, style, speakerBoost, once.\n */\nexport function parseJsonVoiceDirective(\n text: string,\n): { directive: TtsDirective; cleanedText: string } | null {\n const firstNewline = text.indexOf(\"\\n\");\n if (firstNewline === -1) return null;\n\n const firstLine = text.slice(0, firstNewline).trim();\n if (!firstLine.startsWith(\"{\") || !firstLine.endsWith(\"}\")) return null;\n\n try {\n const obj = JSON.parse(firstLine) as Record<string, unknown>;\n\n // Must have at least one voice-related key\n const voiceKeys = [\n \"voice\",\n \"voice_id\",\n \"voiceId\",\n \"model\",\n \"model_id\",\n \"modelId\",\n \"speed\",\n \"rate\",\n ];\n const hasVoiceKey = voiceKeys.some((k) => k in obj);\n if (!hasVoiceKey) return null;\n\n const directive: TtsDirective = {};\n\n const voice = obj.voice ?? obj.voice_id ?? obj.voiceId;\n if (typeof voice === \"string\") directive.voice = voice;\n\n const model = obj.model ?? obj.model_id ?? obj.modelId;\n if (typeof model === \"string\") directive.model = model;\n\n const speed =\n typeof obj.speed === \"number\"\n ? obj.speed\n : typeof obj.rate === \"number\"\n ? obj.rate\n : undefined;\n if (speed !== undefined) directive.speed = speed;\n\n const cleanedText = text.slice(firstNewline + 1).trim();\n return { directive, cleanedText };\n } catch {\n return null;\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
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
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
9
  ],
10
- "mappings": "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",
11
- "debugId": "049CD93507972CAC64756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "3D14662809B323CC64756E2164756E21",
12
12
  "names": []
13
13
  }
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/index.ts
2
2
  import {
3
+ EventType,
3
4
  ModelType,
4
5
  logger
5
6
  } from "@elizaos/core";
@@ -74,6 +75,45 @@ function normalizeProvider(raw) {
74
75
  return;
75
76
  }
76
77
  }
78
+ function parseJsonVoiceDirective(text) {
79
+ const firstNewline = text.indexOf(`
80
+ `);
81
+ if (firstNewline === -1)
82
+ return null;
83
+ const firstLine = text.slice(0, firstNewline).trim();
84
+ if (!firstLine.startsWith("{") || !firstLine.endsWith("}"))
85
+ return null;
86
+ try {
87
+ const obj = JSON.parse(firstLine);
88
+ const voiceKeys = [
89
+ "voice",
90
+ "voice_id",
91
+ "voiceId",
92
+ "model",
93
+ "model_id",
94
+ "modelId",
95
+ "speed",
96
+ "rate"
97
+ ];
98
+ const hasVoiceKey = voiceKeys.some((k) => (k in obj));
99
+ if (!hasVoiceKey)
100
+ return null;
101
+ const directive = {};
102
+ const voice = obj.voice ?? obj.voice_id ?? obj.voiceId;
103
+ if (typeof voice === "string")
104
+ directive.voice = voice;
105
+ const model = obj.model ?? obj.model_id ?? obj.modelId;
106
+ if (typeof model === "string")
107
+ directive.model = model;
108
+ const speed = typeof obj.speed === "number" ? obj.speed : typeof obj.rate === "number" ? obj.rate : undefined;
109
+ if (speed !== undefined)
110
+ directive.speed = speed;
111
+ const cleanedText = text.slice(firstNewline + 1).trim();
112
+ return { directive, cleanedText };
113
+ } catch {
114
+ return null;
115
+ }
116
+ }
77
117
  function stripTtsDirectives(text) {
78
118
  let cleaned = text;
79
119
  cleaned = cleaned.replace(TTS_TEXT_PATTERN, "");
@@ -322,6 +362,49 @@ var ttsPlugin = {
322
362
  name: "tts",
323
363
  description: "Text-to-speech coordinator with multi-provider support and [[tts]] directives",
324
364
  providers: [ttsConfigProvider],
365
+ events: {
366
+ [EventType.HOOK_MESSAGE_SENDING]: [
367
+ async (payload) => {
368
+ if (!payload.runtime || !payload.content || payload.cancel)
369
+ return;
370
+ const runtime = payload.runtime;
371
+ const roomId = payload.to ?? "";
372
+ const config = getTtsConfig(roomId);
373
+ const jsonDirective = parseJsonVoiceDirective(payload.content);
374
+ const tagDirective = parseTtsDirective(payload.content);
375
+ const hasDirective = Boolean(jsonDirective || tagDirective);
376
+ const inboundAudio = Boolean(payload.metadata && "inboundAudio" in payload.metadata && payload.metadata.inboundAudio);
377
+ if (!shouldApplyTts(config, { inboundAudio, hasDirective })) {
378
+ return;
379
+ }
380
+ const directive = jsonDirective?.directive ?? tagDirective;
381
+ const textToSpeak = jsonDirective ? jsonDirective.cleanedText : getTtsText(payload.content, tagDirective);
382
+ if (!textToSpeak.trim())
383
+ return;
384
+ try {
385
+ const result = await synthesize(runtime, {
386
+ text: textToSpeak,
387
+ provider: directive?.provider ?? config.provider,
388
+ voice: directive?.voice ?? config.voice,
389
+ model: directive?.model ?? config.model,
390
+ speed: directive?.speed
391
+ });
392
+ payload.metadata = {
393
+ ...payload.metadata,
394
+ ttsAudio: result.audio,
395
+ ttsFormat: result.format,
396
+ ttsProvider: result.provider
397
+ };
398
+ if (jsonDirective) {
399
+ payload.content = jsonDirective.cleanedText;
400
+ }
401
+ logger.debug(`[TTS] Generated ${result.format} audio via ${result.provider} for room ${roomId}`);
402
+ } catch (err) {
403
+ logger.warn(`[TTS] Failed to generate speech: ${err instanceof Error ? err.message : String(err)}`);
404
+ }
405
+ }
406
+ ]
407
+ },
325
408
  config: {
326
409
  TTS_AUTO_MODE: "off",
327
410
  TTS_DEFAULT_PROVIDER: "auto",
@@ -515,6 +598,7 @@ export {
515
598
  setTtsConfig,
516
599
  processTextForTts,
517
600
  parseTtsDirective,
601
+ parseJsonVoiceDirective,
518
602
  maybeApplyTts,
519
603
  isProviderAvailable,
520
604
  hasTtsDirective,
@@ -530,4 +614,4 @@ export {
530
614
  DEFAULT_TTS_CONFIG
531
615
  };
532
616
 
533
- //# debugId=554A80245C4B812D64756E2164756E21
617
+ //# debugId=BEE2BF68B69ADA6664756E2164756E21
package/dist/index.js.map CHANGED
@@ -2,12 +2,12 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/index.ts", "../src/directive-parser.ts", "../src/text-processor.ts", "../src/types.ts"],
4
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",
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 EventType,\n type HookMessageSendingPayload,\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 parseJsonVoiceDirective,\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 events: {\n [EventType.HOOK_MESSAGE_SENDING]: [\n async (payload: HookMessageSendingPayload) => {\n if (!payload.runtime || !payload.content || payload.cancel) return;\n\n const runtime = payload.runtime;\n const roomId = payload.to ?? \"\";\n const config = getTtsConfig(roomId);\n\n // Check JSON voice directive (openclaw-classic format)\n const jsonDirective = parseJsonVoiceDirective(payload.content);\n\n // Check [[tts]] directive\n const tagDirective = parseTtsDirective(payload.content);\n const hasDirective = Boolean(jsonDirective || tagDirective);\n\n const inboundAudio = Boolean(\n payload.metadata &&\n \"inboundAudio\" in payload.metadata &&\n payload.metadata.inboundAudio,\n );\n\n if (!shouldApplyTts(config, { inboundAudio, hasDirective })) {\n return;\n }\n\n // Determine text to synthesize and any directive overrides\n const directive = jsonDirective?.directive ?? tagDirective;\n const textToSpeak = jsonDirective\n ? jsonDirective.cleanedText\n : getTtsText(payload.content, tagDirective);\n\n if (!textToSpeak.trim()) return;\n\n try {\n const result = await synthesize(runtime, {\n text: textToSpeak,\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 // Attach TTS audio to message metadata for the channel to send\n payload.metadata = {\n ...payload.metadata,\n ttsAudio: result.audio,\n ttsFormat: result.format,\n ttsProvider: result.provider,\n };\n\n // If we parsed a JSON voice directive, replace the content with cleaned text\n if (jsonDirective) {\n payload.content = jsonDirective.cleanedText;\n }\n\n logger.debug(\n `[TTS] Generated ${result.format} audio via ${result.provider} for room ${roomId}`,\n );\n } catch (err) {\n logger.warn(\n `[TTS] Failed to generate speech: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n },\n ],\n },\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 * Parse a JSON voice directive from the first line of the reply.\n *\n * openclaw-classic format:\n * { \"voice\": \"abc123\", \"once\": true }\n * Actual reply text here...\n *\n * Supported keys: voice/voice_id/voiceId, model/model_id/modelId,\n * speed, rate, stability, similarity, style, speakerBoost, once.\n */\nexport function parseJsonVoiceDirective(\n text: string,\n): { directive: TtsDirective; cleanedText: string } | null {\n const firstNewline = text.indexOf(\"\\n\");\n if (firstNewline === -1) return null;\n\n const firstLine = text.slice(0, firstNewline).trim();\n if (!firstLine.startsWith(\"{\") || !firstLine.endsWith(\"}\")) return null;\n\n try {\n const obj = JSON.parse(firstLine) as Record<string, unknown>;\n\n // Must have at least one voice-related key\n const voiceKeys = [\n \"voice\",\n \"voice_id\",\n \"voiceId\",\n \"model\",\n \"model_id\",\n \"modelId\",\n \"speed\",\n \"rate\",\n ];\n const hasVoiceKey = voiceKeys.some((k) => k in obj);\n if (!hasVoiceKey) return null;\n\n const directive: TtsDirective = {};\n\n const voice = obj.voice ?? obj.voice_id ?? obj.voiceId;\n if (typeof voice === \"string\") directive.voice = voice;\n\n const model = obj.model ?? obj.model_id ?? obj.modelId;\n if (typeof model === \"string\") directive.model = model;\n\n const speed =\n typeof obj.speed === \"number\"\n ? obj.speed\n : typeof obj.rate === \"number\"\n ? obj.rate\n : undefined;\n if (speed !== undefined) directive.speed = speed;\n\n const cleanedText = text.slice(firstNewline + 1).trim();\n return { directive, cleanedText };\n } catch {\n return null;\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
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
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
9
  ],
10
- "mappings": "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",
11
- "debugId": "554A80245C4B812D64756E2164756E21",
10
+ "mappings": "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",
11
+ "debugId": "BEE2BF68B69ADA6664756E2164756E21",
12
12
  "names": []
13
13
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/plugin-tts",
3
- "version": "2.0.0-alpha.3",
3
+ "version": "2.0.0-alpha.5",
4
4
  "type": "module",
5
5
  "main": "dist/cjs/index.cjs",
6
6
  "module": "dist/index.js",
@@ -29,17 +29,19 @@
29
29
  "devDependencies": {
30
30
  "@types/bun": "^1.2.22",
31
31
  "@types/node": "^24.5.2",
32
- "prettier": "3.6.2",
33
- "typescript": "^5.9.2"
32
+ "typescript": "^5.9.2",
33
+ "@biomejs/biome": "^2.3.11"
34
34
  },
35
35
  "scripts": {
36
36
  "build": "bun run build.ts",
37
37
  "dev": "bun --hot build.ts",
38
38
  "test": "elizaos test",
39
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"
40
+ "format": "bunx @biomejs/biome format --write .",
41
+ "format:check": "bunx @biomejs/biome format .",
42
+ "lint": "bunx @biomejs/biome check --write --unsafe .",
43
+ "lint:check": "bunx @biomejs/biome check .",
44
+ "typecheck": "tsc --noEmit"
43
45
  },
44
46
  "publishConfig": {
45
47
  "access": "public"