@elizaos/plugin-elevenlabs 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +22 -1
- package/dist/index.js +217 -18
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,28 @@ import { Plugin } from '@elizaos/core';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Represents the ElevenLabs plugin.
|
|
5
|
-
* This plugin provides functionality
|
|
5
|
+
* This plugin provides text-to-speech functionality using the ElevenLabs API.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - High-quality voice synthesis
|
|
9
|
+
* - Support for multiple voice models and settings
|
|
10
|
+
* - Automatic WAV header prepending for PCM formats
|
|
11
|
+
* - Configurable voice parameters (stability, similarity, style)
|
|
12
|
+
* - Stream-based audio output for efficient memory usage
|
|
13
|
+
*
|
|
14
|
+
* Required environment variables:
|
|
15
|
+
* - ELEVENLABS_API_KEY or ELEVENLABS_XI_API_KEY: Your ElevenLabs API key
|
|
16
|
+
*
|
|
17
|
+
* Optional environment variables:
|
|
18
|
+
* - ELEVENLABS_VOICE_ID: Voice ID to use (default: EXAVITQu4vr4xnSDxMaL)
|
|
19
|
+
* - ELEVENLABS_MODEL_ID: Model to use (default: eleven_monolingual_v1)
|
|
20
|
+
* - ELEVENLABS_VOICE_STABILITY: Voice stability 0-1 (default: 0.5)
|
|
21
|
+
* - ELEVENLABS_VOICE_SIMILARITY_BOOST: Voice similarity 0-1 (default: 0.75)
|
|
22
|
+
* - ELEVENLABS_VOICE_STYLE: Voice style 0-1 (default: 0)
|
|
23
|
+
* - ELEVENLABS_VOICE_USE_SPEAKER_BOOST: Enable speaker boost (default: true)
|
|
24
|
+
* - ELEVENLABS_OPTIMIZE_STREAMING_LATENCY: Latency optimization 0-4 (default: 0)
|
|
25
|
+
* - ELEVENLABS_OUTPUT_FORMAT: Output format (default: pcm_16000)
|
|
26
|
+
*
|
|
6
27
|
* @type {Plugin}
|
|
7
28
|
*/
|
|
8
29
|
declare const elevenLabsPlugin: Plugin;
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ModelType,
|
|
4
4
|
logger,
|
|
5
|
-
prependWavHeader,
|
|
6
5
|
parseBooleanFromText
|
|
7
6
|
} from "@elizaos/core";
|
|
8
|
-
import { Readable } from "node:stream";
|
|
7
|
+
import { Readable, PassThrough } from "node:stream";
|
|
8
|
+
import { Buffer } from "node:buffer";
|
|
9
9
|
function getVoiceSettings(runtime) {
|
|
10
|
-
const getSetting = (key, fallback = "") =>
|
|
10
|
+
const getSetting = (key, fallback = "") => runtime.getSetting(key) || process.env[key] || fallback;
|
|
11
11
|
return {
|
|
12
12
|
apiKey: getSetting("ELEVENLABS_API_KEY") || getSetting("ELEVENLABS_XI_API_KEY"),
|
|
13
13
|
voiceId: getSetting("ELEVENLABS_VOICE_ID", "EXAVITQu4vr4xnSDxMaL"),
|
|
@@ -17,9 +17,7 @@ function getVoiceSettings(runtime) {
|
|
|
17
17
|
outputFormat: getSetting("ELEVENLABS_OUTPUT_FORMAT", "pcm_16000"),
|
|
18
18
|
similarity: getSetting("ELEVENLABS_VOICE_SIMILARITY_BOOST", "0.75"),
|
|
19
19
|
style: getSetting("ELEVENLABS_VOICE_STYLE", "0"),
|
|
20
|
-
speakerBoost: parseBooleanFromText(
|
|
21
|
-
getSetting("ELEVENLABS_VOICE_USE_SPEAKER_BOOST", "true")
|
|
22
|
-
)
|
|
20
|
+
speakerBoost: parseBooleanFromText(getSetting("ELEVENLABS_VOICE_USE_SPEAKER_BOOST", "true") + "")
|
|
23
21
|
};
|
|
24
22
|
}
|
|
25
23
|
async function fetchSpeech(runtime, text) {
|
|
@@ -50,24 +48,62 @@ async function fetchSpeech(runtime, text) {
|
|
|
50
48
|
const errorBody = JSON.parse(errorBodyString);
|
|
51
49
|
if (response.status === 401 && errorBody.detail?.status === "quota_exceeded") {
|
|
52
50
|
logger.log("ElevenLabs quota exceeded");
|
|
53
|
-
throw
|
|
51
|
+
throw new Error("QUOTA_EXCEEDED");
|
|
54
52
|
}
|
|
55
|
-
|
|
53
|
+
logger.error(
|
|
54
|
+
`Received status ${response.status} from Eleven Labs API: ${JSON.stringify(errorBody)}`
|
|
55
|
+
);
|
|
56
|
+
throw new Error(
|
|
56
57
|
`Received status ${response.status} from Eleven Labs API: ${JSON.stringify(errorBody)}`
|
|
57
58
|
);
|
|
58
59
|
}
|
|
59
60
|
if (!response.body) {
|
|
60
|
-
|
|
61
|
+
logger.error("Empty response body from Eleven Labs API");
|
|
62
|
+
throw new Error("Empty response body from Eleven Labs API");
|
|
61
63
|
}
|
|
62
64
|
return Readable.fromWeb(response.body);
|
|
63
65
|
} catch (error) {
|
|
64
66
|
const msg = error instanceof Error ? error.message : String(error);
|
|
65
|
-
|
|
67
|
+
logger.error(`ElevenLabs fetchSpeech error: ${msg}`);
|
|
68
|
+
throw error instanceof Error ? error : new Error(msg);
|
|
66
69
|
}
|
|
67
70
|
}
|
|
71
|
+
function getWavHeader(audioLength, sampleRate, channelCount = 1, bitsPerSample = 16) {
|
|
72
|
+
const wavHeader = Buffer.alloc(44);
|
|
73
|
+
wavHeader.write("RIFF", 0);
|
|
74
|
+
wavHeader.writeUInt32LE(36 + audioLength, 4);
|
|
75
|
+
wavHeader.write("WAVE", 8);
|
|
76
|
+
wavHeader.write("fmt ", 12);
|
|
77
|
+
wavHeader.writeUInt32LE(16, 16);
|
|
78
|
+
wavHeader.writeUInt16LE(1, 20);
|
|
79
|
+
wavHeader.writeUInt16LE(channelCount, 22);
|
|
80
|
+
wavHeader.writeUInt32LE(sampleRate, 24);
|
|
81
|
+
wavHeader.writeUInt32LE(sampleRate * bitsPerSample * channelCount / 8, 28);
|
|
82
|
+
wavHeader.writeUInt16LE(bitsPerSample * channelCount / 8, 32);
|
|
83
|
+
wavHeader.writeUInt16LE(bitsPerSample, 34);
|
|
84
|
+
wavHeader.write("data", 36);
|
|
85
|
+
wavHeader.writeUInt32LE(audioLength, 40);
|
|
86
|
+
return wavHeader;
|
|
87
|
+
}
|
|
88
|
+
function prependWavHeader(readable, audioLength, sampleRate, channelCount = 1, bitsPerSample = 16) {
|
|
89
|
+
const wavHeader = getWavHeader(audioLength, sampleRate, channelCount, bitsPerSample);
|
|
90
|
+
let pushedHeader = false;
|
|
91
|
+
const passThrough = new PassThrough();
|
|
92
|
+
readable.on("data", (data) => {
|
|
93
|
+
if (!pushedHeader) {
|
|
94
|
+
passThrough.push(wavHeader);
|
|
95
|
+
pushedHeader = true;
|
|
96
|
+
}
|
|
97
|
+
passThrough.push(data);
|
|
98
|
+
});
|
|
99
|
+
readable.on("end", () => {
|
|
100
|
+
passThrough.end();
|
|
101
|
+
});
|
|
102
|
+
return passThrough;
|
|
103
|
+
}
|
|
68
104
|
var elevenLabsPlugin = {
|
|
69
105
|
name: "elevenLabs",
|
|
70
|
-
description: "ElevenLabs
|
|
106
|
+
description: "High-quality text-to-speech synthesis using ElevenLabs API with support for multiple voices and languages",
|
|
71
107
|
models: {
|
|
72
108
|
[ModelType.TEXT_TO_SPEECH]: async (runtime, text) => {
|
|
73
109
|
const settings = getVoiceSettings(runtime);
|
|
@@ -83,7 +119,8 @@ var elevenLabsPlugin = {
|
|
|
83
119
|
) : stream;
|
|
84
120
|
} catch (error) {
|
|
85
121
|
const msg = error instanceof Error ? error.message : String(error);
|
|
86
|
-
|
|
122
|
+
logger.error(`ElevenLabs model error: ${msg}`);
|
|
123
|
+
throw error instanceof Error ? error : new Error(msg);
|
|
87
124
|
}
|
|
88
125
|
}
|
|
89
126
|
},
|
|
@@ -94,21 +131,183 @@ var elevenLabsPlugin = {
|
|
|
94
131
|
{
|
|
95
132
|
name: "Eleven Labs API key validation",
|
|
96
133
|
fn: async (runtime) => {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
134
|
+
const settings = getVoiceSettings(runtime);
|
|
135
|
+
if (!settings.apiKey) {
|
|
136
|
+
throw new Error("Missing API key: Please provide a valid Eleven Labs API key.");
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
name: "Voice settings validation",
|
|
142
|
+
fn: async (runtime) => {
|
|
143
|
+
const settings = getVoiceSettings(runtime);
|
|
144
|
+
if (!settings.voiceId) {
|
|
145
|
+
throw new Error("Missing voice ID configuration");
|
|
146
|
+
}
|
|
147
|
+
const stability = parseFloat(settings.stability);
|
|
148
|
+
if (isNaN(stability) || stability < 0 || stability > 1) {
|
|
149
|
+
throw new Error("Voice stability must be between 0 and 1");
|
|
150
|
+
}
|
|
151
|
+
const similarity = parseFloat(settings.similarity);
|
|
152
|
+
if (isNaN(similarity) || similarity < 0 || similarity > 1) {
|
|
153
|
+
throw new Error("Voice similarity boost must be between 0 and 1");
|
|
154
|
+
}
|
|
155
|
+
logger.success("Voice settings validated successfully");
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
name: "WAV header generation",
|
|
160
|
+
fn: async () => {
|
|
161
|
+
const header = getWavHeader(1024, 16e3, 1, 16);
|
|
162
|
+
if (header.length !== 44) {
|
|
163
|
+
throw new Error("WAV header should be exactly 44 bytes");
|
|
164
|
+
}
|
|
165
|
+
if (header.toString("ascii", 0, 4) !== "RIFF") {
|
|
166
|
+
throw new Error("WAV header should start with RIFF");
|
|
167
|
+
}
|
|
168
|
+
if (header.toString("ascii", 8, 12) !== "WAVE") {
|
|
169
|
+
throw new Error("WAV header should contain WAVE identifier");
|
|
101
170
|
}
|
|
171
|
+
logger.success("WAV header generation test passed");
|
|
102
172
|
}
|
|
103
173
|
},
|
|
104
174
|
{
|
|
105
|
-
name: "Eleven Labs API
|
|
175
|
+
name: "Eleven Labs API connectivity",
|
|
106
176
|
fn: async (runtime) => {
|
|
177
|
+
const settings = getVoiceSettings(runtime);
|
|
178
|
+
if (!settings.apiKey) {
|
|
179
|
+
logger.warn("Skipping API connectivity test - no API key provided");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
107
182
|
try {
|
|
108
183
|
await fetchSpeech(runtime, "test");
|
|
184
|
+
logger.success("API connectivity test passed");
|
|
109
185
|
} catch (error) {
|
|
110
186
|
const msg = error instanceof Error ? error.message : String(error);
|
|
111
|
-
|
|
187
|
+
if (msg.includes("QUOTA_EXCEEDED")) {
|
|
188
|
+
logger.warn("API quota exceeded - test skipped");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
logger.error(`API connectivity test failed: ${msg}`);
|
|
192
|
+
throw new Error(`API connectivity test failed: ${msg}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "ElevenLabs TTS Generation with stream validation",
|
|
198
|
+
fn: async (runtime) => {
|
|
199
|
+
const settings = getVoiceSettings(runtime);
|
|
200
|
+
if (!settings.apiKey) {
|
|
201
|
+
logger.warn("Skipping TTS generation test - no API key provided");
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
logger.info("[ElevenLabs Test] Starting TTS Generation test");
|
|
205
|
+
const testText = "Hello from ElevenLabs test.";
|
|
206
|
+
try {
|
|
207
|
+
const audioStream = await runtime.useModel(ModelType.TEXT_TO_SPEECH, testText);
|
|
208
|
+
if (!(audioStream instanceof Readable)) {
|
|
209
|
+
throw new Error("TTS output is not a Readable stream");
|
|
210
|
+
}
|
|
211
|
+
logger.info(
|
|
212
|
+
"[ElevenLabs Test] TTS output is a Readable stream. Validating stream..."
|
|
213
|
+
);
|
|
214
|
+
let dataReceived = false;
|
|
215
|
+
let totalBytes = 0;
|
|
216
|
+
let streamEnded = false;
|
|
217
|
+
let streamError = null;
|
|
218
|
+
let headerValidated = false;
|
|
219
|
+
audioStream.on("data", (chunk) => {
|
|
220
|
+
dataReceived = true;
|
|
221
|
+
totalBytes += chunk.length;
|
|
222
|
+
if (!headerValidated && settings.outputFormat.startsWith("pcm_") && chunk.length >= 44) {
|
|
223
|
+
const header = chunk.slice(0, 4).toString("ascii");
|
|
224
|
+
if (header === "RIFF") {
|
|
225
|
+
headerValidated = true;
|
|
226
|
+
logger.info("[ElevenLabs Test] WAV header validated");
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
logger.info(
|
|
230
|
+
`[ElevenLabs Test] Received chunk: ${chunk.length} bytes, total: ${totalBytes} bytes`
|
|
231
|
+
);
|
|
232
|
+
});
|
|
233
|
+
audioStream.on("end", () => {
|
|
234
|
+
logger.info("[ElevenLabs Test] Audio stream ended successfully");
|
|
235
|
+
streamEnded = true;
|
|
236
|
+
});
|
|
237
|
+
audioStream.on("error", (err) => {
|
|
238
|
+
logger.error("[ElevenLabs Test] Audio stream error:", err);
|
|
239
|
+
streamError = err;
|
|
240
|
+
streamEnded = true;
|
|
241
|
+
});
|
|
242
|
+
await new Promise((resolve, reject) => {
|
|
243
|
+
const timeoutId = setTimeout(() => {
|
|
244
|
+
if (!streamEnded) {
|
|
245
|
+
reject(
|
|
246
|
+
new Error("[ElevenLabs Test] Stream processing timed out after 15 seconds")
|
|
247
|
+
);
|
|
248
|
+
} else {
|
|
249
|
+
resolve();
|
|
250
|
+
}
|
|
251
|
+
}, 15e3);
|
|
252
|
+
audioStream.on("end", () => {
|
|
253
|
+
clearTimeout(timeoutId);
|
|
254
|
+
resolve();
|
|
255
|
+
});
|
|
256
|
+
audioStream.on("error", (err) => {
|
|
257
|
+
clearTimeout(timeoutId);
|
|
258
|
+
reject(err);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
if (streamError) {
|
|
262
|
+
throw streamError;
|
|
263
|
+
}
|
|
264
|
+
if (!dataReceived) {
|
|
265
|
+
throw new Error("[ElevenLabs Test] No audio data was received from the stream");
|
|
266
|
+
}
|
|
267
|
+
if (totalBytes === 0) {
|
|
268
|
+
throw new Error("[ElevenLabs Test] Received empty audio stream");
|
|
269
|
+
}
|
|
270
|
+
logger.success(
|
|
271
|
+
`[ElevenLabs Test] TTS test completed successfully. Received ${totalBytes} bytes of audio data`
|
|
272
|
+
);
|
|
273
|
+
} catch (error) {
|
|
274
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
275
|
+
if (msg.includes("QUOTA_EXCEEDED")) {
|
|
276
|
+
logger.warn("[ElevenLabs Test] API quota exceeded - test skipped");
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
if (msg.includes("Missing API key") || msg.includes("401")) {
|
|
280
|
+
logger.warn("[ElevenLabs Test] Test skipped due to missing or invalid API key");
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
logger.error("[ElevenLabs Test] TTS Generation test failed:", msg);
|
|
284
|
+
throw new Error(`TTS Generation test failed: ${msg}`);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
name: "Output format handling",
|
|
290
|
+
fn: async (runtime) => {
|
|
291
|
+
const settings = getVoiceSettings(runtime);
|
|
292
|
+
const pcmFormats = ["pcm_16000", "pcm_22050", "pcm_24000", "pcm_44100"];
|
|
293
|
+
for (const format of pcmFormats) {
|
|
294
|
+
if (format.startsWith("pcm_")) {
|
|
295
|
+
const sampleRate = Number.parseInt(format.slice(4));
|
|
296
|
+
if (isNaN(sampleRate) || sampleRate <= 0) {
|
|
297
|
+
throw new Error(`Invalid PCM format: ${format}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (settings.outputFormat.startsWith("pcm_")) {
|
|
302
|
+
const sampleRate = Number.parseInt(settings.outputFormat.slice(4));
|
|
303
|
+
if (isNaN(sampleRate) || sampleRate <= 0) {
|
|
304
|
+
throw new Error(`Invalid output format configuration: ${settings.outputFormat}`);
|
|
305
|
+
}
|
|
306
|
+
logger.success(
|
|
307
|
+
`Output format validated: ${settings.outputFormat} with sample rate ${sampleRate}Hz`
|
|
308
|
+
);
|
|
309
|
+
} else {
|
|
310
|
+
logger.success(`Output format validated: ${settings.outputFormat} (non-PCM format)`);
|
|
112
311
|
}
|
|
113
312
|
}
|
|
114
313
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n type IAgentRuntime,\n ModelType,\n type Plugin,\n logger,\n prependWavHeader,\n parseBooleanFromText,\n} from \"@elizaos/core\";\nimport { Readable } from \"node:stream\";\n\n/**\n * Function to retrieve voice settings based on runtime and environment variables.\n * @param {IAgentRuntime} runtime - The agent runtime object.\n * @returns {Object} - Object containing various voice settings.\n */\nfunction getVoiceSettings(runtime: IAgentRuntime) {\n const getSetting = (key: string, fallback = \"\") =>\n process.env[key] || runtime.getSetting(key) || fallback;\n\n return {\n apiKey:\n getSetting(\"ELEVENLABS_API_KEY\") || getSetting(\"ELEVENLABS_XI_API_KEY\"),\n voiceId: getSetting(\"ELEVENLABS_VOICE_ID\", \"EXAVITQu4vr4xnSDxMaL\"),\n model: getSetting(\"ELEVENLABS_MODEL_ID\", \"eleven_monolingual_v1\"),\n stability: getSetting(\"ELEVENLABS_VOICE_STABILITY\", \"0.5\"),\n latency: getSetting(\"ELEVENLABS_OPTIMIZE_STREAMING_LATENCY\", \"0\"),\n outputFormat: getSetting(\"ELEVENLABS_OUTPUT_FORMAT\", \"pcm_16000\"),\n similarity: getSetting(\"ELEVENLABS_VOICE_SIMILARITY_BOOST\", \"0.75\"),\n style: getSetting(\"ELEVENLABS_VOICE_STYLE\", \"0\"),\n speakerBoost: parseBooleanFromText(\n getSetting(\"ELEVENLABS_VOICE_USE_SPEAKER_BOOST\", \"true\")\n ),\n };\n}\n\n/**\n * Fetch speech from Eleven Labs API using given text and runtime settings.\n * @param {IAgentRuntime} runtime - The runtime interface containing necessary data for the API call.\n * @param {string} text - The text to be converted into speech.\n * @returns {Promise<Readable>} A promise resolving to a readable stream of the fetched speech.\n */\nasync function fetchSpeech(runtime: IAgentRuntime, text: string) {\n const settings = getVoiceSettings(runtime);\n try {\n const response = await fetch(\n `https://api.elevenlabs.io/v1/text-to-speech/${settings.voiceId}/stream?optimize_streaming_latency=${settings.latency}&output_format=${settings.outputFormat}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"xi-api-key\": settings.apiKey,\n },\n body: JSON.stringify({\n model_id: settings.model,\n text,\n voice_settings: {\n similarity_boost: settings.similarity,\n stability: settings.stability,\n style: settings.style,\n use_speaker_boost: settings.speakerBoost,\n },\n }),\n }\n );\n if (response.status !== 200) {\n const errorBodyString = await response.text();\n const errorBody = JSON.parse(errorBodyString);\n\n if (\n response.status === 401 &&\n errorBody.detail?.status === \"quota_exceeded\"\n ) {\n logger.log(\"ElevenLabs quota exceeded\");\n throw logger.error(\"QUOTA_EXCEEDED\");\n }\n throw logger.error(\n `Received status ${response.status} from Eleven Labs API: ${JSON.stringify(errorBody)}`\n );\n }\n\n if (!response.body) {\n throw logger.error(\"Empty response body from Eleven Labs API\");\n }\n\n return Readable.fromWeb(response.body);\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw logger.error(msg);\n }\n}\n\n/**\n * Represents the ElevenLabs plugin.\n * This plugin provides functionality related to ElevenLabs API, including text to speech conversion.\n * @type {Plugin}\n */\nexport const elevenLabsPlugin: Plugin = {\n name: \"elevenLabs\",\n description: \"ElevenLabs plugin\",\n models: {\n [ModelType.TEXT_TO_SPEECH]: async (runtime, text) => {\n const settings = getVoiceSettings(runtime);\n logger.log(`[ElevenLabs] Using TEXT_TO_SPEECH model: ${settings.model}`);\n try {\n const stream = await fetchSpeech(runtime, text);\n return settings.outputFormat.startsWith(\"pcm_\")\n ? prependWavHeader(\n stream,\n 1024 * 1024 * 100,\n Number.parseInt(settings.outputFormat.slice(4)),\n 1,\n 16\n )\n : stream;\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n throw logger.error(msg);\n }\n },\n },\n tests: [\n {\n name: \"test eleven labs\",\n tests: [\n {\n name: \"Eleven Labs API key validation\",\n fn: async (runtime: IAgentRuntime) => {\n if (!getVoiceSettings(runtime).apiKey) {\n throw new Error(\n \"Missing API key: Please provide a valid Eleven Labs API key.\"\n );\n }\n },\n },\n {\n name: \"Eleven Labs API response\",\n fn: async (runtime: IAgentRuntime) => {\n try {\n await fetchSpeech(runtime, \"test\");\n } catch (error: unknown) {\n const msg =\n error instanceof Error ? error.message : String(error);\n throw logger.error(msg);\n }\n },\n },\n ],\n },\n ],\n};\nexport default elevenLabsPlugin;\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n type IAgentRuntime,\n ModelType,\n type Plugin,\n logger,\n parseBooleanFromText,\n} from '@elizaos/core';\nimport { Readable, PassThrough } from 'node:stream';\nimport { Buffer } from 'node:buffer';\n\n/**\n * Voice settings configuration for ElevenLabs API\n */\ninterface VoiceSettings {\n apiKey: string;\n voiceId: string;\n model: string;\n stability: string;\n latency: string;\n outputFormat: string;\n similarity: string;\n style: string;\n speakerBoost: boolean;\n}\n\n/**\n * Function to retrieve voice settings based on runtime and environment variables.\n * @param {IAgentRuntime} runtime - The agent runtime object.\n * @returns {VoiceSettings} - Object containing various voice settings.\n */\nfunction getVoiceSettings(runtime: IAgentRuntime): VoiceSettings {\n const getSetting = (key: string, fallback = '') =>\n runtime.getSetting(key) || process.env[key] || fallback;\n return {\n apiKey: getSetting('ELEVENLABS_API_KEY') || getSetting('ELEVENLABS_XI_API_KEY'),\n voiceId: getSetting('ELEVENLABS_VOICE_ID', 'EXAVITQu4vr4xnSDxMaL'),\n model: getSetting('ELEVENLABS_MODEL_ID', 'eleven_monolingual_v1'),\n stability: getSetting('ELEVENLABS_VOICE_STABILITY', '0.5'),\n latency: getSetting('ELEVENLABS_OPTIMIZE_STREAMING_LATENCY', '0'),\n outputFormat: getSetting('ELEVENLABS_OUTPUT_FORMAT', 'pcm_16000'),\n similarity: getSetting('ELEVENLABS_VOICE_SIMILARITY_BOOST', '0.75'),\n style: getSetting('ELEVENLABS_VOICE_STYLE', '0'),\n speakerBoost: parseBooleanFromText(getSetting('ELEVENLABS_VOICE_USE_SPEAKER_BOOST', 'true') + ''),\n };\n}\n\n/**\n * Fetch speech from Eleven Labs API using given text and runtime settings.\n * @param {IAgentRuntime} runtime - The runtime interface containing necessary data for the API call.\n * @param {string} text - The text to be converted into speech.\n * @returns {Promise<Readable>} A promise resolving to a readable stream of the fetched speech.\n */\nasync function fetchSpeech(runtime: IAgentRuntime, text: string) {\n const settings = getVoiceSettings(runtime);\n try {\n const response = await fetch(\n `https://api.elevenlabs.io/v1/text-to-speech/${settings.voiceId}/stream?optimize_streaming_latency=${settings.latency}&output_format=${settings.outputFormat}`,\n {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'xi-api-key': settings.apiKey,\n },\n body: JSON.stringify({\n model_id: settings.model,\n text,\n voice_settings: {\n similarity_boost: settings.similarity,\n stability: settings.stability,\n style: settings.style,\n use_speaker_boost: settings.speakerBoost,\n },\n }),\n }\n );\n if (response.status !== 200) {\n const errorBodyString = await response.text();\n const errorBody = JSON.parse(errorBodyString);\n\n if (response.status === 401 && errorBody.detail?.status === 'quota_exceeded') {\n logger.log('ElevenLabs quota exceeded');\n throw new Error('QUOTA_EXCEEDED');\n }\n logger.error(\n `Received status ${response.status} from Eleven Labs API: ${JSON.stringify(errorBody)}`\n );\n throw new Error(\n `Received status ${response.status} from Eleven Labs API: ${JSON.stringify(errorBody)}`\n );\n }\n\n if (!response.body) {\n logger.error('Empty response body from Eleven Labs API');\n throw new Error('Empty response body from Eleven Labs API');\n }\n\n return Readable.fromWeb(response.body);\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`ElevenLabs fetchSpeech error: ${msg}`);\n throw error instanceof Error ? error : new Error(msg);\n }\n}\n\n// Audio Utils\n\n/**\n * Generates a WAV file header based on the provided audio parameters.\n * @param {number} audioLength - The length of the audio data in bytes.\n * @param {number} sampleRate - The sample rate of the audio.\n * @param {number} [channelCount=1] - The number of channels (default is 1).\n * @param {number} [bitsPerSample=16] - The number of bits per sample (default is 16).\n * @returns {Buffer} The WAV file header as a Buffer object.\n */\nfunction getWavHeader(\n audioLength: number,\n sampleRate: number,\n channelCount = 1,\n bitsPerSample = 16\n): Buffer {\n const wavHeader = Buffer.alloc(44);\n wavHeader.write('RIFF', 0);\n wavHeader.writeUInt32LE(36 + audioLength, 4); // Length of entire file in bytes minus 8\n wavHeader.write('WAVE', 8);\n wavHeader.write('fmt ', 12);\n wavHeader.writeUInt32LE(16, 16); // Length of format data\n wavHeader.writeUInt16LE(1, 20); // Type of format (1 is PCM)\n wavHeader.writeUInt16LE(channelCount, 22); // Number of channels\n wavHeader.writeUInt32LE(sampleRate, 24); // Sample rate\n wavHeader.writeUInt32LE((sampleRate * bitsPerSample * channelCount) / 8, 28); // Byte rate\n wavHeader.writeUInt16LE((bitsPerSample * channelCount) / 8, 32); // Block align ((BitsPerSample * Channels) / 8)\n wavHeader.writeUInt16LE(bitsPerSample, 34); // Bits per sample\n wavHeader.write('data', 36); // Data chunk header\n wavHeader.writeUInt32LE(audioLength, 40); // Data chunk size\n return wavHeader;\n}\n\n/**\n * Prepends a WAV header to a readable stream of audio data.\n *\n * @param {Readable} readable - The readable stream containing the audio data.\n * @param {number} audioLength - The length of the audio data in bytes.\n * @param {number} sampleRate - The sample rate of the audio data.\n * @param {number} [channelCount=1] - The number of channels in the audio data (default is 1).\n * @param {number} [bitsPerSample=16] - The number of bits per sample in the audio data (default is 16).\n * @returns {PassThrough} A new pass-through stream with the WAV header prepended to the audio data.\n */\nfunction prependWavHeader(\n readable: Readable,\n audioLength: number,\n sampleRate: number,\n channelCount = 1,\n bitsPerSample = 16\n): PassThrough {\n const wavHeader = getWavHeader(audioLength, sampleRate, channelCount, bitsPerSample);\n let pushedHeader = false;\n const passThrough = new PassThrough();\n readable.on('data', (data: Buffer) => {\n if (!pushedHeader) {\n passThrough.push(wavHeader);\n pushedHeader = true;\n }\n passThrough.push(data);\n });\n readable.on('end', () => {\n passThrough.end();\n });\n return passThrough;\n}\n\n/**\n * Represents the ElevenLabs plugin.\n * This plugin provides text-to-speech functionality using the ElevenLabs API.\n *\n * Features:\n * - High-quality voice synthesis\n * - Support for multiple voice models and settings\n * - Automatic WAV header prepending for PCM formats\n * - Configurable voice parameters (stability, similarity, style)\n * - Stream-based audio output for efficient memory usage\n *\n * Required environment variables:\n * - ELEVENLABS_API_KEY or ELEVENLABS_XI_API_KEY: Your ElevenLabs API key\n *\n * Optional environment variables:\n * - ELEVENLABS_VOICE_ID: Voice ID to use (default: EXAVITQu4vr4xnSDxMaL)\n * - ELEVENLABS_MODEL_ID: Model to use (default: eleven_monolingual_v1)\n * - ELEVENLABS_VOICE_STABILITY: Voice stability 0-1 (default: 0.5)\n * - ELEVENLABS_VOICE_SIMILARITY_BOOST: Voice similarity 0-1 (default: 0.75)\n * - ELEVENLABS_VOICE_STYLE: Voice style 0-1 (default: 0)\n * - ELEVENLABS_VOICE_USE_SPEAKER_BOOST: Enable speaker boost (default: true)\n * - ELEVENLABS_OPTIMIZE_STREAMING_LATENCY: Latency optimization 0-4 (default: 0)\n * - ELEVENLABS_OUTPUT_FORMAT: Output format (default: pcm_16000)\n *\n * @type {Plugin}\n */\nexport const elevenLabsPlugin: Plugin = {\n name: 'elevenLabs',\n description:\n 'High-quality text-to-speech synthesis using ElevenLabs API with support for multiple voices and languages',\n models: {\n [ModelType.TEXT_TO_SPEECH]: async (runtime, text) => {\n const settings = getVoiceSettings(runtime);\n logger.log(`[ElevenLabs] Using TEXT_TO_SPEECH model: ${settings.model}`);\n try {\n const stream = await fetchSpeech(runtime, text);\n return settings.outputFormat.startsWith('pcm_')\n ? prependWavHeader(\n stream,\n 1024 * 1024 * 100,\n Number.parseInt(settings.outputFormat.slice(4)),\n 1,\n 16\n )\n : stream;\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n logger.error(`ElevenLabs model error: ${msg}`);\n throw error instanceof Error ? error : new Error(msg);\n }\n },\n },\n tests: [\n {\n name: 'test eleven labs',\n tests: [\n {\n name: 'Eleven Labs API key validation',\n fn: async (runtime: IAgentRuntime) => {\n const settings = getVoiceSettings(runtime);\n if (!settings.apiKey) {\n throw new Error('Missing API key: Please provide a valid Eleven Labs API key.');\n }\n },\n },\n {\n name: 'Voice settings validation',\n fn: async (runtime: IAgentRuntime) => {\n const settings = getVoiceSettings(runtime);\n\n // Validate that all required settings are present\n if (!settings.voiceId) {\n throw new Error('Missing voice ID configuration');\n }\n\n // Validate numeric settings\n const stability = parseFloat(settings.stability);\n if (isNaN(stability) || stability < 0 || stability > 1) {\n throw new Error('Voice stability must be between 0 and 1');\n }\n\n const similarity = parseFloat(settings.similarity);\n if (isNaN(similarity) || similarity < 0 || similarity > 1) {\n throw new Error('Voice similarity boost must be between 0 and 1');\n }\n\n logger.success('Voice settings validated successfully');\n },\n },\n {\n name: 'WAV header generation',\n fn: async () => {\n // Test WAV header generation\n const header = getWavHeader(1024, 16000, 1, 16);\n\n if (header.length !== 44) {\n throw new Error('WAV header should be exactly 44 bytes');\n }\n\n // Check RIFF header\n if (header.toString('ascii', 0, 4) !== 'RIFF') {\n throw new Error('WAV header should start with RIFF');\n }\n\n // Check WAVE format\n if (header.toString('ascii', 8, 12) !== 'WAVE') {\n throw new Error('WAV header should contain WAVE identifier');\n }\n\n logger.success('WAV header generation test passed');\n },\n },\n {\n name: 'Eleven Labs API connectivity',\n fn: async (runtime: IAgentRuntime) => {\n const settings = getVoiceSettings(runtime);\n if (!settings.apiKey) {\n logger.warn('Skipping API connectivity test - no API key provided');\n return;\n }\n\n try {\n await fetchSpeech(runtime, 'test');\n logger.success('API connectivity test passed');\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n if (msg.includes('QUOTA_EXCEEDED')) {\n logger.warn('API quota exceeded - test skipped');\n return;\n }\n logger.error(`API connectivity test failed: ${msg}`);\n throw new Error(`API connectivity test failed: ${msg}`);\n }\n },\n },\n {\n name: 'ElevenLabs TTS Generation with stream validation',\n fn: async (runtime: IAgentRuntime) => {\n const settings = getVoiceSettings(runtime);\n if (!settings.apiKey) {\n logger.warn('Skipping TTS generation test - no API key provided');\n return;\n }\n\n logger.info('[ElevenLabs Test] Starting TTS Generation test');\n const testText = 'Hello from ElevenLabs test.';\n\n try {\n const audioStream = await runtime.useModel(ModelType.TEXT_TO_SPEECH, testText);\n\n if (!(audioStream instanceof Readable)) {\n throw new Error('TTS output is not a Readable stream');\n }\n\n logger.info(\n '[ElevenLabs Test] TTS output is a Readable stream. Validating stream...'\n );\n\n let dataReceived = false;\n let totalBytes = 0;\n let streamEnded = false;\n let streamError: Error | null = null;\n let headerValidated = false;\n\n audioStream.on('data', (chunk: Buffer) => {\n dataReceived = true;\n totalBytes += chunk.length;\n\n // Validate WAV header on first chunk if PCM format\n if (\n !headerValidated &&\n settings.outputFormat.startsWith('pcm_') &&\n chunk.length >= 44\n ) {\n const header = chunk.slice(0, 4).toString('ascii');\n if (header === 'RIFF') {\n headerValidated = true;\n logger.info('[ElevenLabs Test] WAV header validated');\n }\n }\n\n logger.info(\n `[ElevenLabs Test] Received chunk: ${chunk.length} bytes, total: ${totalBytes} bytes`\n );\n });\n\n audioStream.on('end', () => {\n logger.info('[ElevenLabs Test] Audio stream ended successfully');\n streamEnded = true;\n });\n\n audioStream.on('error', (err) => {\n logger.error('[ElevenLabs Test] Audio stream error:', err);\n streamError = err;\n streamEnded = true;\n });\n\n // Wait for the stream to end or error, with a timeout\n await new Promise<void>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n if (!streamEnded) {\n reject(\n new Error('[ElevenLabs Test] Stream processing timed out after 15 seconds')\n );\n } else {\n resolve();\n }\n }, 15000);\n\n audioStream.on('end', () => {\n clearTimeout(timeoutId);\n resolve();\n });\n\n audioStream.on('error', (err) => {\n clearTimeout(timeoutId);\n reject(err);\n });\n });\n\n if (streamError) {\n throw streamError;\n }\n\n if (!dataReceived) {\n throw new Error('[ElevenLabs Test] No audio data was received from the stream');\n }\n\n if (totalBytes === 0) {\n throw new Error('[ElevenLabs Test] Received empty audio stream');\n }\n\n logger.success(\n `[ElevenLabs Test] TTS test completed successfully. Received ${totalBytes} bytes of audio data`\n );\n } catch (error: unknown) {\n const msg = error instanceof Error ? error.message : String(error);\n\n if (msg.includes('QUOTA_EXCEEDED')) {\n logger.warn('[ElevenLabs Test] API quota exceeded - test skipped');\n return;\n }\n\n if (msg.includes('Missing API key') || msg.includes('401')) {\n logger.warn('[ElevenLabs Test] Test skipped due to missing or invalid API key');\n return;\n }\n\n logger.error('[ElevenLabs Test] TTS Generation test failed:', msg);\n throw new Error(`TTS Generation test failed: ${msg}`);\n }\n },\n },\n {\n name: 'Output format handling',\n fn: async (runtime: IAgentRuntime) => {\n const settings = getVoiceSettings(runtime);\n\n // Test PCM format detection\n const pcmFormats = ['pcm_16000', 'pcm_22050', 'pcm_24000', 'pcm_44100'];\n for (const format of pcmFormats) {\n if (format.startsWith('pcm_')) {\n const sampleRate = Number.parseInt(format.slice(4));\n if (isNaN(sampleRate) || sampleRate <= 0) {\n throw new Error(`Invalid PCM format: ${format}`);\n }\n }\n }\n\n // Test current output format\n if (settings.outputFormat.startsWith('pcm_')) {\n const sampleRate = Number.parseInt(settings.outputFormat.slice(4));\n if (isNaN(sampleRate) || sampleRate <= 0) {\n throw new Error(`Invalid output format configuration: ${settings.outputFormat}`);\n }\n logger.success(\n `Output format validated: ${settings.outputFormat} with sample rate ${sampleRate}Hz`\n );\n } else {\n logger.success(`Output format validated: ${settings.outputFormat} (non-PCM format)`);\n }\n },\n },\n ],\n },\n ],\n};\nexport default elevenLabsPlugin;\n"],"mappings":";AAAA;AAAA,EAEE;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AACP,SAAS,UAAU,mBAAmB;AACtC,SAAS,cAAc;AAsBvB,SAAS,iBAAiB,SAAuC;AAC/D,QAAM,aAAa,CAAC,KAAa,WAAW,OAC1C,QAAQ,WAAW,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK;AACjD,SAAO;AAAA,IACL,QAAQ,WAAW,oBAAoB,KAAK,WAAW,uBAAuB;AAAA,IAC9E,SAAS,WAAW,uBAAuB,sBAAsB;AAAA,IACjE,OAAO,WAAW,uBAAuB,uBAAuB;AAAA,IAChE,WAAW,WAAW,8BAA8B,KAAK;AAAA,IACzD,SAAS,WAAW,yCAAyC,GAAG;AAAA,IAChE,cAAc,WAAW,4BAA4B,WAAW;AAAA,IAChE,YAAY,WAAW,qCAAqC,MAAM;AAAA,IAClE,OAAO,WAAW,0BAA0B,GAAG;AAAA,IAC/C,cAAc,qBAAqB,WAAW,sCAAsC,MAAM,IAAI,EAAE;AAAA,EAClG;AACF;AAQA,eAAe,YAAY,SAAwB,MAAc;AAC/D,QAAM,WAAW,iBAAiB,OAAO;AACzC,MAAI;AACF,UAAM,WAAW,MAAM;AAAA,MACrB,+CAA+C,SAAS,OAAO,sCAAsC,SAAS,OAAO,kBAAkB,SAAS,YAAY;AAAA,MAC5J;AAAA,QACE,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,cAAc,SAAS;AAAA,QACzB;AAAA,QACA,MAAM,KAAK,UAAU;AAAA,UACnB,UAAU,SAAS;AAAA,UACnB;AAAA,UACA,gBAAgB;AAAA,YACd,kBAAkB,SAAS;AAAA,YAC3B,WAAW,SAAS;AAAA,YACpB,OAAO,SAAS;AAAA,YAChB,mBAAmB,SAAS;AAAA,UAC9B;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,kBAAkB,MAAM,SAAS,KAAK;AAC5C,YAAM,YAAY,KAAK,MAAM,eAAe;AAE5C,UAAI,SAAS,WAAW,OAAO,UAAU,QAAQ,WAAW,kBAAkB;AAC5E,eAAO,IAAI,2BAA2B;AACtC,cAAM,IAAI,MAAM,gBAAgB;AAAA,MAClC;AACA,aAAO;AAAA,QACL,mBAAmB,SAAS,MAAM,0BAA0B,KAAK,UAAU,SAAS,CAAC;AAAA,MACvF;AACA,YAAM,IAAI;AAAA,QACR,mBAAmB,SAAS,MAAM,0BAA0B,KAAK,UAAU,SAAS,CAAC;AAAA,MACvF;AAAA,IACF;AAEA,QAAI,CAAC,SAAS,MAAM;AAClB,aAAO,MAAM,0CAA0C;AACvD,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAEA,WAAO,SAAS,QAAQ,SAAS,IAAI;AAAA,EACvC,SAAS,OAAgB;AACvB,UAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,WAAO,MAAM,iCAAiC,GAAG,EAAE;AACnD,UAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,GAAG;AAAA,EACtD;AACF;AAYA,SAAS,aACP,aACA,YACA,eAAe,GACf,gBAAgB,IACR;AACR,QAAM,YAAY,OAAO,MAAM,EAAE;AACjC,YAAU,MAAM,QAAQ,CAAC;AACzB,YAAU,cAAc,KAAK,aAAa,CAAC;AAC3C,YAAU,MAAM,QAAQ,CAAC;AACzB,YAAU,MAAM,QAAQ,EAAE;AAC1B,YAAU,cAAc,IAAI,EAAE;AAC9B,YAAU,cAAc,GAAG,EAAE;AAC7B,YAAU,cAAc,cAAc,EAAE;AACxC,YAAU,cAAc,YAAY,EAAE;AACtC,YAAU,cAAe,aAAa,gBAAgB,eAAgB,GAAG,EAAE;AAC3E,YAAU,cAAe,gBAAgB,eAAgB,GAAG,EAAE;AAC9D,YAAU,cAAc,eAAe,EAAE;AACzC,YAAU,MAAM,QAAQ,EAAE;AAC1B,YAAU,cAAc,aAAa,EAAE;AACvC,SAAO;AACT;AAYA,SAAS,iBACP,UACA,aACA,YACA,eAAe,GACf,gBAAgB,IACH;AACb,QAAM,YAAY,aAAa,aAAa,YAAY,cAAc,aAAa;AACnF,MAAI,eAAe;AACnB,QAAM,cAAc,IAAI,YAAY;AACpC,WAAS,GAAG,QAAQ,CAAC,SAAiB;AACpC,QAAI,CAAC,cAAc;AACjB,kBAAY,KAAK,SAAS;AAC1B,qBAAe;AAAA,IACjB;AACA,gBAAY,KAAK,IAAI;AAAA,EACvB,CAAC;AACD,WAAS,GAAG,OAAO,MAAM;AACvB,gBAAY,IAAI;AAAA,EAClB,CAAC;AACD,SAAO;AACT;AA4BO,IAAM,mBAA2B;AAAA,EACtC,MAAM;AAAA,EACN,aACE;AAAA,EACF,QAAQ;AAAA,IACN,CAAC,UAAU,cAAc,GAAG,OAAO,SAAS,SAAS;AACnD,YAAM,WAAW,iBAAiB,OAAO;AACzC,aAAO,IAAI,4CAA4C,SAAS,KAAK,EAAE;AACvE,UAAI;AACF,cAAM,SAAS,MAAM,YAAY,SAAS,IAAI;AAC9C,eAAO,SAAS,aAAa,WAAW,MAAM,IAC1C;AAAA,UACE;AAAA,UACA,OAAO,OAAO;AAAA,UACd,OAAO,SAAS,SAAS,aAAa,MAAM,CAAC,CAAC;AAAA,UAC9C;AAAA,UACA;AAAA,QACF,IACA;AAAA,MACN,SAAS,OAAgB;AACvB,cAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,eAAO,MAAM,2BAA2B,GAAG,EAAE;AAC7C,cAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,GAAG;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AAAA,EACA,OAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,QACL;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAA2B;AACpC,kBAAM,WAAW,iBAAiB,OAAO;AACzC,gBAAI,CAAC,SAAS,QAAQ;AACpB,oBAAM,IAAI,MAAM,8DAA8D;AAAA,YAChF;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAA2B;AACpC,kBAAM,WAAW,iBAAiB,OAAO;AAGzC,gBAAI,CAAC,SAAS,SAAS;AACrB,oBAAM,IAAI,MAAM,gCAAgC;AAAA,YAClD;AAGA,kBAAM,YAAY,WAAW,SAAS,SAAS;AAC/C,gBAAI,MAAM,SAAS,KAAK,YAAY,KAAK,YAAY,GAAG;AACtD,oBAAM,IAAI,MAAM,yCAAyC;AAAA,YAC3D;AAEA,kBAAM,aAAa,WAAW,SAAS,UAAU;AACjD,gBAAI,MAAM,UAAU,KAAK,aAAa,KAAK,aAAa,GAAG;AACzD,oBAAM,IAAI,MAAM,gDAAgD;AAAA,YAClE;AAEA,mBAAO,QAAQ,uCAAuC;AAAA,UACxD;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,YAAY;AAEd,kBAAM,SAAS,aAAa,MAAM,MAAO,GAAG,EAAE;AAE9C,gBAAI,OAAO,WAAW,IAAI;AACxB,oBAAM,IAAI,MAAM,uCAAuC;AAAA,YACzD;AAGA,gBAAI,OAAO,SAAS,SAAS,GAAG,CAAC,MAAM,QAAQ;AAC7C,oBAAM,IAAI,MAAM,mCAAmC;AAAA,YACrD;AAGA,gBAAI,OAAO,SAAS,SAAS,GAAG,EAAE,MAAM,QAAQ;AAC9C,oBAAM,IAAI,MAAM,2CAA2C;AAAA,YAC7D;AAEA,mBAAO,QAAQ,mCAAmC;AAAA,UACpD;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAA2B;AACpC,kBAAM,WAAW,iBAAiB,OAAO;AACzC,gBAAI,CAAC,SAAS,QAAQ;AACpB,qBAAO,KAAK,sDAAsD;AAClE;AAAA,YACF;AAEA,gBAAI;AACF,oBAAM,YAAY,SAAS,MAAM;AACjC,qBAAO,QAAQ,8BAA8B;AAAA,YAC/C,SAAS,OAAgB;AACvB,oBAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACjE,kBAAI,IAAI,SAAS,gBAAgB,GAAG;AAClC,uBAAO,KAAK,mCAAmC;AAC/C;AAAA,cACF;AACA,qBAAO,MAAM,iCAAiC,GAAG,EAAE;AACnD,oBAAM,IAAI,MAAM,iCAAiC,GAAG,EAAE;AAAA,YACxD;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAA2B;AACpC,kBAAM,WAAW,iBAAiB,OAAO;AACzC,gBAAI,CAAC,SAAS,QAAQ;AACpB,qBAAO,KAAK,oDAAoD;AAChE;AAAA,YACF;AAEA,mBAAO,KAAK,gDAAgD;AAC5D,kBAAM,WAAW;AAEjB,gBAAI;AACF,oBAAM,cAAc,MAAM,QAAQ,SAAS,UAAU,gBAAgB,QAAQ;AAE7E,kBAAI,EAAE,uBAAuB,WAAW;AACtC,sBAAM,IAAI,MAAM,qCAAqC;AAAA,cACvD;AAEA,qBAAO;AAAA,gBACL;AAAA,cACF;AAEA,kBAAI,eAAe;AACnB,kBAAI,aAAa;AACjB,kBAAI,cAAc;AAClB,kBAAI,cAA4B;AAChC,kBAAI,kBAAkB;AAEtB,0BAAY,GAAG,QAAQ,CAAC,UAAkB;AACxC,+BAAe;AACf,8BAAc,MAAM;AAGpB,oBACE,CAAC,mBACD,SAAS,aAAa,WAAW,MAAM,KACvC,MAAM,UAAU,IAChB;AACA,wBAAM,SAAS,MAAM,MAAM,GAAG,CAAC,EAAE,SAAS,OAAO;AACjD,sBAAI,WAAW,QAAQ;AACrB,sCAAkB;AAClB,2BAAO,KAAK,wCAAwC;AAAA,kBACtD;AAAA,gBACF;AAEA,uBAAO;AAAA,kBACL,qCAAqC,MAAM,MAAM,kBAAkB,UAAU;AAAA,gBAC/E;AAAA,cACF,CAAC;AAED,0BAAY,GAAG,OAAO,MAAM;AAC1B,uBAAO,KAAK,mDAAmD;AAC/D,8BAAc;AAAA,cAChB,CAAC;AAED,0BAAY,GAAG,SAAS,CAAC,QAAQ;AAC/B,uBAAO,MAAM,yCAAyC,GAAG;AACzD,8BAAc;AACd,8BAAc;AAAA,cAChB,CAAC;AAGD,oBAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,sBAAM,YAAY,WAAW,MAAM;AACjC,sBAAI,CAAC,aAAa;AAChB;AAAA,sBACE,IAAI,MAAM,gEAAgE;AAAA,oBAC5E;AAAA,kBACF,OAAO;AACL,4BAAQ;AAAA,kBACV;AAAA,gBACF,GAAG,IAAK;AAER,4BAAY,GAAG,OAAO,MAAM;AAC1B,+BAAa,SAAS;AACtB,0BAAQ;AAAA,gBACV,CAAC;AAED,4BAAY,GAAG,SAAS,CAAC,QAAQ;AAC/B,+BAAa,SAAS;AACtB,yBAAO,GAAG;AAAA,gBACZ,CAAC;AAAA,cACH,CAAC;AAED,kBAAI,aAAa;AACf,sBAAM;AAAA,cACR;AAEA,kBAAI,CAAC,cAAc;AACjB,sBAAM,IAAI,MAAM,8DAA8D;AAAA,cAChF;AAEA,kBAAI,eAAe,GAAG;AACpB,sBAAM,IAAI,MAAM,+CAA+C;AAAA,cACjE;AAEA,qBAAO;AAAA,gBACL,+DAA+D,UAAU;AAAA,cAC3E;AAAA,YACF,SAAS,OAAgB;AACvB,oBAAM,MAAM,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAEjE,kBAAI,IAAI,SAAS,gBAAgB,GAAG;AAClC,uBAAO,KAAK,qDAAqD;AACjE;AAAA,cACF;AAEA,kBAAI,IAAI,SAAS,iBAAiB,KAAK,IAAI,SAAS,KAAK,GAAG;AAC1D,uBAAO,KAAK,kEAAkE;AAC9E;AAAA,cACF;AAEA,qBAAO,MAAM,iDAAiD,GAAG;AACjE,oBAAM,IAAI,MAAM,+BAA+B,GAAG,EAAE;AAAA,YACtD;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,IAAI,OAAO,YAA2B;AACpC,kBAAM,WAAW,iBAAiB,OAAO;AAGzC,kBAAM,aAAa,CAAC,aAAa,aAAa,aAAa,WAAW;AACtE,uBAAW,UAAU,YAAY;AAC/B,kBAAI,OAAO,WAAW,MAAM,GAAG;AAC7B,sBAAM,aAAa,OAAO,SAAS,OAAO,MAAM,CAAC,CAAC;AAClD,oBAAI,MAAM,UAAU,KAAK,cAAc,GAAG;AACxC,wBAAM,IAAI,MAAM,uBAAuB,MAAM,EAAE;AAAA,gBACjD;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,SAAS,aAAa,WAAW,MAAM,GAAG;AAC5C,oBAAM,aAAa,OAAO,SAAS,SAAS,aAAa,MAAM,CAAC,CAAC;AACjE,kBAAI,MAAM,UAAU,KAAK,cAAc,GAAG;AACxC,sBAAM,IAAI,MAAM,wCAAwC,SAAS,YAAY,EAAE;AAAA,cACjF;AACA,qBAAO;AAAA,gBACL,4BAA4B,SAAS,YAAY,qBAAqB,UAAU;AAAA,cAClF;AAAA,YACF,OAAO;AACL,qBAAO,QAAQ,4BAA4B,SAAS,YAAY,mBAAmB;AAAA,YACrF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AACA,IAAO,gBAAQ;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elizaos/plugin-elevenlabs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -22,12 +22,14 @@
|
|
|
22
22
|
"dist"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@elizaos/core": "
|
|
25
|
+
"@elizaos/core": "latest",
|
|
26
|
+
"@elizaos/plugin-anthropic": "latest",
|
|
26
27
|
"tsup": "8.4.0"
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
30
|
"build": "tsup",
|
|
30
31
|
"dev": "tsup --watch",
|
|
32
|
+
"test": "elizaos test",
|
|
31
33
|
"clean": "rm -rf dist .turbo node_modules .turbo-tsconfig.json tsconfig.tsbuildinfo",
|
|
32
34
|
"format": "prettier --write ./src",
|
|
33
35
|
"format:check": "prettier --check ./src",
|