@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.
- package/dist/cjs/index.cjs +84 -1
- package/dist/cjs/index.cjs.map +4 -4
- package/dist/index.js +85 -1
- package/dist/index.js.map +4 -4
- package/package.json +8 -6
package/dist/cjs/index.cjs
CHANGED
|
@@ -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=
|
|
643
|
+
//# debugId=3D14662809B323CC64756E2164756E21
|
package/dist/cjs/index.cjs.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": "
|
|
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=
|
|
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": ";AAWA;AAAA;AAAA;AAAA;;;ACEA,IAAM,wBAAwB;AAC9B,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAKnB,SAAS,eAAe,CAAC,MAAuB;AAAA,EACrD,OAAO,sBAAsB,KAAK,IAAI,KAAK,iBAAiB,KAAK,IAAI;AAAA;AAMhE,SAAS,iBAAiB,CAAC,MAAmC;AAAA,EACnE,IAAI,CAAC,gBAAgB,IAAI,GAAG;AAAA,IAC1B,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,YAA0B,CAAC;AAAA,EAGjC,MAAM,YAAY,KAAK,MAAM,gBAAgB;AAAA,EAC7C,IAAI,WAAW;AAAA,IAEb,MAAM,YAAY,UAAU;AAAA,IAC5B,MAAM,eAAe,UAAU,QAAQ,IAAI,IAAI;AAAA,IAC/C,MAAM,aAAa,UAAU,YAAY,IAAI;AAAA,IAC7C,UAAU,OAAO,UAAU,MAAM,cAAc,UAAU,EAAE,KAAK;AAAA,EAClE;AAAA,EAGA,sBAAsB,YAAY;AAAA,EAClC,IAAI;AAAA,EACJ,QAAQ,QAAQ,sBAAsB,KAAK,IAAI,OAAO,MAAM;AAAA,IAC1D,MAAM,SAAS,MAAM;AAAA,IACrB,IAAI,QAAQ;AAAA,MACV,IAAI;AAAA,MACJ,kBAAkB,YAAY;AAAA,MAC9B,QAAQ,UAAU,kBAAkB,KAAK,MAAM,OAAO,MAAM;AAAA,QAC1D,MAAM,MAAM,QAAQ,GAAG,YAAY;AAAA,QACnC,MAAM,QAAQ,QAAQ;AAAA,QAEtB,QAAQ;AAAA,eACD;AAAA,YACH,UAAU,WAAW,kBAAkB,KAAK;AAAA,YAC5C;AAAA,eACG;AAAA,YACH,UAAU,QAAQ;AAAA,YAClB;AAAA,eACG;AAAA,YACH,UAAU,QAAQ;AAAA,YAClB;AAAA,eACG;AAAA,YACH,UAAU,QAAQ,WAAW,KAAK;AAAA,YAClC;AAAA;AAAA,MAEN;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OAAO;AAAA;AAMT,SAAS,iBAAiB,CAAC,KAAsC;AAAA,EAC/D,MAAM,aAAa,IAAI,YAAY,EAAE,KAAK;AAAA,EAC1C,QAAQ;AAAA,SACD;AAAA,SACA;AAAA,SACA;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,SACA;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,SACA;AAAA,SACA;AAAA,MACH,OAAO;AAAA,SACJ;AAAA,SACA;AAAA,SACA;AAAA,MACH,OAAO;AAAA;AAAA,MAEP;AAAA;AAAA;AAOC,SAAS,kBAAkB,CAAC,MAAsB;AAAA,EACvD,IAAI,UAAU;AAAA,EAGd,UAAU,QAAQ,QAAQ,kBAAkB,EAAE;AAAA,EAG9C,UAAU,QAAQ,QAAQ,uBAAuB,EAAE;AAAA,EAGnD,OAAO,QAAQ,QAAQ,QAAQ,GAAG,EAAE,KAAK;AAAA;AAOpC,SAAS,UAAU,CACxB,MACA,WACQ;AAAA,EACR,IAAI,WAAW,MAAM;AAAA,IACnB,OAAO,UAAU;AAAA,EACnB;AAAA,EACA,OAAO,mBAAmB,IAAI;AAAA;;;ACtHzB,SAAS,eAAe,CAAC,MAAsB;AAAA,EACpD,IAAI,UAAU;AAAA,EAGd,UAAU,QAAQ,QAAQ,mBAAmB,cAAc;AAAA,EAG3D,UAAU,QAAQ,QAAQ,YAAY,QAAQ;AAAA,EAG9C,UAAU,QAAQ,QAAQ,sBAAsB,QAAQ;AAAA,EAGxD,UAAU,QAAQ,QAAQ,oBAAoB,IAAI;AAAA,EAClD,UAAU,QAAQ,QAAQ,gBAAgB,IAAI;AAAA,EAC9C,UAAU,QAAQ,QAAQ,gBAAgB,IAAI;AAAA,EAC9C,UAAU,QAAQ,QAAQ,cAAc,IAAI;AAAA,EAG5C,UAAU,QAAQ,QAAQ,gBAAgB,EAAE;AAAA,EAG5C,UAAU,QAAQ,QAAQ,0BAA0B,IAAI;AAAA,EAGxD,UAAU,QAAQ,QAAQ,YAAY,EAAE;AAAA,EAGxC,UAAU,QAAQ,QAAQ,WAAW;AAAA,CAAI;AAAA,EAGzC,UAAU,QAAQ,KAAK;AAAA,EAEvB,OAAO;AAAA;AAMF,SAAS,YAAY,CAAC,MAAc,WAA2B;AAAA,EACpE,IAAI,KAAK,UAAU,WAAW;AAAA,IAC5B,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,YAAY,KAAK,MAAM,GAAG,SAAS;AAAA,EACzC,MAAM,kBAAkB,KAAK,IAC3B,UAAU,YAAY,IAAI,GAC1B,UAAU,YAAY,IAAI,GAC1B,UAAU,YAAY,IAAI,GAC1B,UAAU,YAAY;AAAA,CAAK,GAC3B,UAAU,YAAY;AAAA,CAAK,GAC3B,UAAU,YAAY;AAAA,CAAK,CAC7B;AAAA,EAEA,IAAI,kBAAkB,YAAY,KAAK;AAAA,IACrC,OAAO,UAAU,MAAM,GAAG,kBAAkB,CAAC,EAAE,KAAK;AAAA,EACtD;AAAA,EAGA,MAAM,YAAY,UAAU,YAAY,GAAG;AAAA,EAC3C,IAAI,YAAY,YAAY,KAAK;AAAA,IAC/B,OAAO,UAAU,MAAM,GAAG,SAAS,EAAE,KAAK,IAAI;AAAA,EAChD;AAAA,EAEA,OAAO,UAAU,KAAK,IAAI;AAAA;AAM5B,eAAsB,eAAe,CACnC,SACA,MACA,WACiB;AAAA,EACjB,IAAI;AAAA,IACF,MAAM,SAAS,mCAAmC;AAAA;AAAA,EAA+G;AAAA,IAEjK,MAAM,WAAW,MAAM,QAAQ,SAAS,cAAc;AAAA,MACpD;AAAA,MACA,WAAW,KAAK,KAAK,YAAY,CAAC;AAAA,IACpC,CAAC;AAAA,IAED,IAAI,OAAO,aAAa,UAAU;AAAA,MAChC,OAAO,SAAS,MAAM,GAAG,SAAS;AAAA,IACpC;AAAA,IAGA,OAAO,aAAa,MAAM,SAAS;AAAA,IACnC,MAAM;AAAA,IAEN,OAAO,aAAa,MAAM,SAAS;AAAA;AAAA;AAQvC,eAAsB,iBAAiB,CACrC,SACA,MACA,SAKwB;AAAA,EACxB,QAAQ,WAAW,WAAW,YAAY,OAAO;AAAA,EAGjD,IAAI,YAAY,gBAAgB,IAAI;AAAA,EAGpC,IAAI,UAAU,SAAS,WAAW;AAAA,IAChC,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,UAAU,SAAS,WAAW;AAAA,IAChC,IAAI,WAAW;AAAA,MACb,YAAY,MAAM,gBAAgB,SAAS,WAAW,SAAS;AAAA,IACjE,EAAO;AAAA,MACL,YAAY,aAAa,WAAW,SAAS;AAAA;AAAA,EAEjD;AAAA,EAEA,OAAO;AAAA;;;ACrFF,IAAM,qBAAgC;AAAA,EAC3C,UAAU;AAAA,EACV,MAAM;AAAA,EACN,WAAW;AAAA,EACX,WAAW;AACb;AAGO,IAAM,wBAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,wBAAuD;AAAA,EAClE,YAAY,CAAC,sBAAsB,YAAY;AAAA,EAC/C,QAAQ,CAAC,gBAAgB;AAAA,EACzB,MAAM,CAAC;AAAA,EACP,gBAAgB,CAAC;AAAA,EACjB,MAAM,CAAC;AACT;;;AH1BA,IAAM,iBAAiB,IAAI;AAKpB,SAAS,YAAY,CAAC,QAA2B;AAAA,EACtD,MAAM,UAAU,eAAe,IAAI,MAAM;AAAA,EACzC,OAAO;AAAA,OACF;AAAA,OACA;AAAA,EACL;AAAA;AAMK,SAAS,YAAY,CAC1B,QACA,QACM;AAAA,EACN,MAAM,WAAW,eAAe,IAAI,MAAM,KAAK,CAAC;AAAA,EAChD,eAAe,IAAI,QAAQ,KAAK,aAAa,OAAO,CAAC;AAAA;AAMhD,SAAS,cAAc,CAAC,QAAsB;AAAA,EACnD,eAAe,OAAO,MAAM;AAAA;AAMvB,SAAS,mBAAmB,CACjC,SACA,UACS;AAAA,EACT,IAAI,aAAa;AAAA,IAAQ,OAAO;AAAA,EAEhC,MAAM,eAAe,sBAAsB;AAAA,EAC3C,IAAI,aAAa,WAAW,GAAG;AAAA,IAC7B,OAAO;AAAA,EACT;AAAA,EAEA,OAAO,aAAa,KAAK,CAAC,QAAQ;AAAA,IAChC,MAAM,QAAQ,QAAQ,WAAW,GAAG;AAAA,IACpC,OAAO,SAAS,OAAO,KAAK,EAAE,KAAK,MAAM;AAAA,GAC1C;AAAA;AAMI,SAAS,eAAe,CAC7B,SACA,WACa;AAAA,EAEb,IACE,aACA,cAAc,UACd,oBAAoB,SAAS,SAAS,GACtC;AAAA,IACA,OAAO;AAAA,EACT;AAAA,EAGA,WAAW,YAAY,uBAAuB;AAAA,IAC5C,IAAI,oBAAoB,SAAS,QAAQ,GAAG;AAAA,MAC1C,OAAO;AAAA,IACT;AAAA,EACF;AAAA,EAGA,OAAO;AAAA;AAMT,eAAsB,UAAU,CAC9B,SACA,SACoB;AAAA,EACpB,MAAM,WAAW,gBAAgB,SAAS,QAAQ,QAAQ;AAAA,EAE1D,OAAO,MAAM,qCAAqC,UAAU;AAAA,EAE5D,MAAM,SAAS;AAAA,IACb,MAAM,QAAQ;AAAA,IACd,OAAO,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf,OAAO,QAAQ;AAAA,IACf;AAAA,EACF;AAAA,EAEA,IAAI;AAAA,IACF,MAAM,QAAQ,MAAM,QAAQ,SAAS,UAAU,gBAAgB,MAAM;AAAA,IAErE,OAAO;AAAA,MACL,OAAO,OAAO,SAAS,KAAK,IAAI,QAAQ,OAAO,KAAK,KAAoB;AAAA,MACxE,QAAQ,QAAQ,UAAU;AAAA,MAC1B;AAAA,IACF;AAAA,IACA,OAAO,OAAO;AAAA,IACd,OAAO,MAAM,+BAA+B,aAAa,OAAO;AAAA,IAChE,MAAM;AAAA;AAAA;AAOH,SAAS,cAAc,CAC5B,QACA,SAKS;AAAA,EACT,QAAQ,SAAS;AAAA,EACjB,QAAQ,cAAc,MAAM,iBAAiB;AAAA,EAG7C,IAAI,SAAS,OAAO;AAAA,IAClB,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,SAAS,UAAU;AAAA,IACrB,OAAO;AAAA,EACT;AAAA,EAGA,IAAI,SAAS,WAAW;AAAA,IACtB,OAAO,QAAQ,YAAY;AAAA,EAC7B;AAAA,EAGA,IAAI,SAAS,UAAU;AAAA,IACrB,OAAO,QAAQ,YAAY;AAAA,EAC7B;AAAA,EAEA,OAAO;AAAA;AAMT,eAAsB,aAAa,CACjC,SACA,QACA,MACA,SAIwB;AAAA,EACxB,MAAM,SAAS,aAAa,MAAM;AAAA,EAClC,MAAM,YAAY,kBAAkB,IAAI;AAAA,EACxC,MAAM,eAAe,QAAQ,SAAS;AAAA,EAGtC,IAAI,CAAC,eAAe,QAAQ,KAAK,SAAS,aAAa,CAAC,GAAG;AAAA,IACzD,OAAO;AAAA,EACT;AAAA,EAGA,MAAM,UAAU,WAAW,MAAM,SAAS;AAAA,EAG1C,MAAM,YAAY,MAAM,kBAAkB,SAAS,SAAS;AAAA,IAC1D,WAAW,OAAO;AAAA,IAClB,WAAW,OAAO;AAAA,EACpB,CAAC;AAAA,EAED,IAAI,CAAC,WAAW;AAAA,IACd,OAAO,MAAM,yCAAyC;AAAA,IACtD,OAAO;AAAA,EACT;AAAA,EAGA,IAAI;AAAA,IACF,MAAM,SAAS,MAAM,WAAW,SAAS;AAAA,MACvC,MAAM;AAAA,MACN,UAAU,WAAW,YAAY,OAAO;AAAA,MACxC,OAAO,WAAW,SAAS,OAAO;AAAA,MAClC,OAAO,WAAW,SAAS,OAAO;AAAA,MAClC,OAAO,WAAW;AAAA,IACpB,CAAC;AAAA,IAED,OAAO,OAAO;AAAA,IACd,OAAO,OAAO;AAAA,IACd,OAAO,MAAM,8BAA8B,OAAO;AAAA,IAClD,OAAO;AAAA;AAAA;AAOJ,SAAS,eAAe,CAAC,QAA2B;AAAA,EACzD,MAAM,QAAkB,CAAC;AAAA,EACzB,MAAM,KAAK,SAAS,OAAO,MAAM;AAAA,EACjC,MAAM,KAAK,aAAa,OAAO,UAAU;AAAA,EACzC,MAAM,KAAK,eAAe,OAAO,WAAW;AAAA,EAC5C,MAAM,KAAK,cAAc,OAAO,YAAY,QAAQ,MAAM;AAAA,EAC1D,IAAI,OAAO,OAAO;AAAA,IAChB,MAAM,KAAK,UAAU,OAAO,OAAO;AAAA,EACrC;AAAA,EACA,OAAO,MAAM,KAAK;AAAA,CAAI;AAAA;AAMjB,IAAM,oBAA8B;AAAA,EACzC,MAAM;AAAA,EACN,aAAa;AAAA,EACb,SAAS;AAAA,OAEH,IAAG,CAAC,SAAS,SAAS,QAAiC;AAAA,IAC3D,MAAM,SAAS,aAAa,QAAQ,MAAM;AAAA,IAC1C,MAAM,eAAe,gBAAgB,SAAS,OAAO,QAAQ;AAAA,IAE7D,OAAO;AAAA,MACL,MAAM,gBAAgB,MAAM;AAAA,MAC5B,QAAQ;AAAA,QACN,SAAS,OAAO;AAAA,QAChB,aAAa,OAAO;AAAA,QACpB,mBAAmB;AAAA,QACnB,cAAc,OAAO;AAAA,QACrB,cAAc,OAAO;AAAA,QACrB,UAAU,OAAO,SAAS;AAAA,MAC5B;AAAA,MACA,MAAM,EAAE,OAAO;AAAA,IACjB;AAAA;AAEJ;AASO,IAAM,YAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,aACE;AAAA,EAEF,WAAW,CAAC,iBAAiB;AAAA,EAE7B,QAAQ;AAAA,IACN,eAAe;AAAA,IACf,sBAAsB;AAAA,IACtB,gBAAgB;AAAA,IAChB,eAAe;AAAA,IACf,mBAAmB;AAAA,EACrB;AAAA,EAEA,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,IAAI,CAAC,gBAAgB,qBAAqB,GAAG;AAAA,cAC3C,MAAM,IAAI,MAAM,iCAAiC;AAAA,YACnD;AAAA,YACA,IAAI,CAAC,gBAAgB,mCAAmC,GAAG;AAAA,cACzD,MAAM,IAAI,MAAM,8CAA8C;AAAA,YAChE;AAAA,YACA,IAAI,CAAC,gBAAgB,gCAAgC,GAAG;AAAA,cACtD,MAAM,IAAI,MAAM,sCAAsC;AAAA,YACxD;AAAA,YACA,IAAI,gBAAgB,mBAAmB,GAAG;AAAA,cACxC,MAAM,IAAI,MAAM,2CAA2C;AAAA,YAC7D;AAAA,YACA,OAAO,QAAQ,yCAAyC;AAAA;AAAA,QAE5D;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,YAAY,kBAChB,yDACF;AAAA,YACA,IAAI,CAAC,WAAW;AAAA,cACd,MAAM,IAAI,MAAM,wBAAwB;AAAA,YAC1C;AAAA,YACA,IAAI,UAAU,aAAa,cAAc;AAAA,cACvC,MAAM,IAAI,MACR,wCAAwC,UAAU,WACpD;AAAA,YACF;AAAA,YACA,IAAI,UAAU,UAAU,SAAS;AAAA,cAC/B,MAAM,IAAI,MACR,gCAAgC,UAAU,QAC5C;AAAA,YACF;AAAA,YACA,IAAI,UAAU,UAAU,KAAK;AAAA,cAC3B,MAAM,IAAI,MAAM,2BAA2B,UAAU,OAAO;AAAA,YAC9D;AAAA,YACA,OAAO,QAAQ,uCAAuC;AAAA;AAAA,QAE1D;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,YAAY,kBAChB,mEACF;AAAA,YACA,IAAI,CAAC,WAAW;AAAA,cACd,MAAM,IAAI,MAAM,wBAAwB;AAAA,YAC1C;AAAA,YACA,IAAI,UAAU,SAAS,wBAAwB;AAAA,cAC7C,MAAM,IAAI,MACR,8CAA8C,UAAU,OAC1D;AAAA,YACF;AAAA,YACA,OAAO,QAAQ,wCAAwC;AAAA;AAAA,QAE3D;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,OACJ;AAAA,YACF,MAAM,WAAW,mBAAmB,IAAI;AAAA,YACxC,IAAI,aAAa,eAAe;AAAA,cAC9B,MAAM,IAAI,MAAM,gCAAgC,WAAW;AAAA,YAC7D;AAAA,YACA,OAAO,QAAQ,yCAAyC;AAAA;AAAA,QAE5D;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,OAAO;AAAA,YACb,MAAM,YAAY,kBAAkB,IAAI;AAAA,YACxC,MAAM,UAAU,WAAW,MAAM,SAAS;AAAA,YAC1C,IAAI,YAAY,cAAc;AAAA,cAC5B,MAAM,IAAI,MAAM,+BAA+B,UAAU;AAAA,YAC3D;AAAA,YACA,OAAO,QAAQ,qCAAqC;AAAA;AAAA,QAExD;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,OAAO;AAAA,YACb,MAAM,YAAY,kBAAkB,IAAI;AAAA,YACxC,MAAM,UAAU,WAAW,MAAM,SAAS;AAAA,YAC1C,IAAI,YAAY,iBAAiB;AAAA,cAC/B,MAAM,IAAI,MAAM,kCAAkC,UAAU;AAAA,YAC9D;AAAA,YACA,OAAO,QAAQ,mCAAmC;AAAA;AAAA,QAEtD;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,OAAO;AAAA,YACb,MAAM,UAAU,gBAAgB,IAAI;AAAA,YACpC,IAAI,YAAY,+BAA+B;AAAA,cAC7C,MAAM,IAAI,MAAM,6BAA6B,UAAU;AAAA,YACzD;AAAA,YACA,OAAO,QAAQ,+BAA+B;AAAA;AAAA,QAElD;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,OACJ;AAAA,YACF,MAAM,YAAY,aAAa,MAAM,EAAE;AAAA,YACvC,IAAI,UAAU,SAAS,IAAI;AAAA,cAEzB,MAAM,IAAI,MACR,uCAAuC,UAAU,QACnD;AAAA,YACF;AAAA,YACA,OAAO,QAAQ,iCAAiC;AAAA;AAAA,QAEpD;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YACrC,MAAM,SAAS;AAAA,YACf,eAAe,MAAM;AAAA,YAErB,aAAa,QAAQ,EAAE,MAAM,UAAU,UAAU,OAAO,CAAC;AAAA,YAEzD,MAAM,SAAS,aAAa,MAAM;AAAA,YAClC,IAAI,OAAO,SAAS,UAAU;AAAA,cAC5B,MAAM,IAAI,MAAM,gCAAgC,OAAO,OAAO;AAAA,YAChE;AAAA,YACA,IAAI,OAAO,aAAa,QAAQ;AAAA,cAC9B,MAAM,IAAI,MACR,kCAAkC,OAAO,WAC3C;AAAA,YACF;AAAA,YAEA,eAAe,MAAM;AAAA,YACrB,OAAO,QAAQ,uCAAuC;AAAA;AAAA,QAE1D;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,aAA4B;AAAA,YAErC,IAAI,eAAe,KAAK,oBAAoB,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG;AAAA,cAC9D,MAAM,IAAI,MAAM,mCAAmC;AAAA,YACrD;AAAA,YAGA,IACE,CAAC,eAAe,KAAK,oBAAoB,MAAM,SAAS,GAAG,CAAC,CAAC,GAC7D;AAAA,cACA,MAAM,IAAI,MAAM,kCAAkC;AAAA,YACpD;AAAA,YAGA,IACE,eAAe,KAAK,oBAAoB,MAAM,UAAU,GAAG,CAAC,CAAC,GAC7D;AAAA,cACA,MAAM,IAAI,MAAM,6CAA6C;AAAA,YAC/D;AAAA,YACA,IACE,CAAC,eACC,KAAK,oBAAoB,MAAM,UAAU,GACzC,EAAE,cAAc,KAAK,CACvB,GACA;AAAA,cACA,MAAM,IAAI,MAAM,sCAAsC;AAAA,YACxD;AAAA,YAGA,IAAI,eAAe,KAAK,oBAAoB,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG;AAAA,cACjE,MAAM,IAAI,MAAM,gDAAgD;AAAA,YAClE;AAAA,YACA,IACE,CAAC,eACC,KAAK,oBAAoB,MAAM,SAAS,GACxC,EAAE,cAAc,KAAK,CACvB,GACA;AAAA,cACA,MAAM,IAAI,MAAM,yCAAyC;AAAA,YAC3D;AAAA,YAEA,OAAO,QAAQ,iCAAiC;AAAA;AAAA,QAEpD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,OAEM,KAAI,CAAC,QAAQ,SAAS;AAAA,IAC1B,OAAO,IAAI,2CAA2C;AAAA,IAEtD,MAAM,WAAY,OAAO,iBAAiC;AAAA,IAC1D,MAAM,WAAY,OAAO,wBAAwC;AAAA,IAEjE,OAAO,IACL,2BAA2B,+BAA+B,UAC5D;AAAA,IAGA,MAAM,YAAY,sBAAsB,OAAO,CAAC,MAC9C,oBAAoB,SAAS,CAAC,CAChC;AAAA,IACA,OAAO,IACL,qCAAqC,UAAU,KAAK,IAAI,KAAK,QAC/D;AAAA;AAEJ;AAEA,IAAe;",
|
|
11
|
-
"debugId": "
|
|
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
|
+
"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
|
-
"
|
|
33
|
-
"
|
|
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": "
|
|
41
|
-
"format:check": "
|
|
42
|
-
"lint": "
|
|
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"
|