@framers/agentos-ext-voice-synthesis 2.0.0 → 2.0.1
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/README.md +66 -8
- package/dist/index.d.ts +17 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +35 -7
- package/dist/index.js.map +1 -1
- package/dist/tools/speechToText.d.ts +77 -0
- package/dist/tools/speechToText.d.ts.map +1 -0
- package/dist/tools/speechToText.js +479 -0
- package/dist/tools/speechToText.js.map +1 -0
- package/manifest.json +20 -5
- package/package.json +6 -2
- package/src/index.ts +38 -7
- package/src/tools/speechToText.ts +650 -0
- package/test/textToSpeech.spec.ts +211 -2
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-provider STT Tool — speech-to-text transcription.
|
|
3
|
+
*
|
|
4
|
+
* Supports: OpenAI Whisper, Deepgram, and Whisper-local/OpenAI-compatible
|
|
5
|
+
* local runtimes behind one stable tool contract.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_OPENAI_BASE_URL = 'https://api.openai.com/v1';
|
|
8
|
+
const DEFAULT_DEEPGRAM_BASE_URL = 'https://api.deepgram.com/v1';
|
|
9
|
+
const DEFAULT_WHISPER_LOCAL_BASE_URL = 'http://127.0.0.1:8080/v1';
|
|
10
|
+
function stripTrailingSlash(value) {
|
|
11
|
+
return value.replace(/\/+$/, '');
|
|
12
|
+
}
|
|
13
|
+
function extensionFromMimeType(mimeType) {
|
|
14
|
+
switch (mimeType) {
|
|
15
|
+
case 'audio/mpeg':
|
|
16
|
+
return 'mp3';
|
|
17
|
+
case 'audio/mp4':
|
|
18
|
+
case 'audio/m4a':
|
|
19
|
+
return 'm4a';
|
|
20
|
+
case 'audio/webm':
|
|
21
|
+
return 'webm';
|
|
22
|
+
case 'audio/ogg':
|
|
23
|
+
case 'audio/opus':
|
|
24
|
+
return 'ogg';
|
|
25
|
+
case 'audio/flac':
|
|
26
|
+
return 'flac';
|
|
27
|
+
case 'audio/wav':
|
|
28
|
+
case 'audio/x-wav':
|
|
29
|
+
default:
|
|
30
|
+
return 'wav';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function normalizeBase64Input(input) {
|
|
34
|
+
const trimmed = input.trim();
|
|
35
|
+
const dataUrlMatch = trimmed.match(/^data:([^;]+);base64,(.+)$/i);
|
|
36
|
+
if (dataUrlMatch) {
|
|
37
|
+
return {
|
|
38
|
+
mimeType: dataUrlMatch[1],
|
|
39
|
+
data: Buffer.from(dataUrlMatch[2], 'base64'),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
data: Buffer.from(trimmed, 'base64'),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function normalizeOpenAiSegments(input) {
|
|
47
|
+
if (!Array.isArray(input))
|
|
48
|
+
return undefined;
|
|
49
|
+
const segments = input
|
|
50
|
+
.filter((segment) => typeof segment === 'object' && segment !== null)
|
|
51
|
+
.map((segment) => {
|
|
52
|
+
const value = segment;
|
|
53
|
+
const words = Array.isArray(value.words)
|
|
54
|
+
? value.words
|
|
55
|
+
.filter((word) => typeof word === 'object' && word !== null)
|
|
56
|
+
.map((word) => {
|
|
57
|
+
const item = word;
|
|
58
|
+
return {
|
|
59
|
+
word: typeof item.word === 'string'
|
|
60
|
+
? item.word
|
|
61
|
+
: typeof item.text === 'string'
|
|
62
|
+
? item.text
|
|
63
|
+
: '',
|
|
64
|
+
start: typeof item.start === 'number' ? item.start : 0,
|
|
65
|
+
end: typeof item.end === 'number' ? item.end : 0,
|
|
66
|
+
confidence: typeof item.confidence === 'number' ? item.confidence : undefined,
|
|
67
|
+
speaker: typeof item.speaker === 'string' || typeof item.speaker === 'number'
|
|
68
|
+
? item.speaker
|
|
69
|
+
: undefined,
|
|
70
|
+
};
|
|
71
|
+
})
|
|
72
|
+
: undefined;
|
|
73
|
+
return {
|
|
74
|
+
text: typeof value.text === 'string' ? value.text : '',
|
|
75
|
+
start: typeof value.start === 'number' ? value.start : 0,
|
|
76
|
+
end: typeof value.end === 'number' ? value.end : 0,
|
|
77
|
+
confidence: typeof value.confidence === 'number' ? value.confidence : undefined,
|
|
78
|
+
speaker: typeof value.speaker === 'string' || typeof value.speaker === 'number'
|
|
79
|
+
? value.speaker
|
|
80
|
+
: undefined,
|
|
81
|
+
words,
|
|
82
|
+
};
|
|
83
|
+
})
|
|
84
|
+
.filter((segment) => segment.text || segment.end > segment.start);
|
|
85
|
+
return segments.length > 0 ? segments : undefined;
|
|
86
|
+
}
|
|
87
|
+
function buildOpenAiFormData(audio, input, model) {
|
|
88
|
+
const form = new FormData();
|
|
89
|
+
form.append('file', new Blob([Uint8Array.from(audio.data)], { type: audio.mimeType }), audio.fileName);
|
|
90
|
+
form.append('model', model);
|
|
91
|
+
form.append('response_format', input.responseFormat ?? 'verbose_json');
|
|
92
|
+
if (input.language)
|
|
93
|
+
form.append('language', input.language);
|
|
94
|
+
if (input.prompt)
|
|
95
|
+
form.append('prompt', input.prompt);
|
|
96
|
+
if (typeof input.temperature === 'number') {
|
|
97
|
+
form.append('temperature', String(input.temperature));
|
|
98
|
+
}
|
|
99
|
+
return form;
|
|
100
|
+
}
|
|
101
|
+
async function parseOpenAiLikeResponse(response, input, provider, model) {
|
|
102
|
+
const responseFormat = input.responseFormat ?? 'verbose_json';
|
|
103
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
104
|
+
if (responseFormat === 'text' || contentType.includes('text/plain')) {
|
|
105
|
+
const text = await response.text();
|
|
106
|
+
return {
|
|
107
|
+
text,
|
|
108
|
+
provider,
|
|
109
|
+
model,
|
|
110
|
+
language: input.language,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const payload = (await response.json());
|
|
114
|
+
return {
|
|
115
|
+
text: typeof payload.text === 'string' ? payload.text : '',
|
|
116
|
+
provider,
|
|
117
|
+
model,
|
|
118
|
+
language: typeof payload.language === 'string' ? payload.language : input.language,
|
|
119
|
+
durationSeconds: typeof payload.duration === 'number'
|
|
120
|
+
? payload.duration
|
|
121
|
+
: typeof payload.duration_seconds === 'number'
|
|
122
|
+
? payload.duration_seconds
|
|
123
|
+
: undefined,
|
|
124
|
+
segments: normalizeOpenAiSegments(payload.segments),
|
|
125
|
+
providerResponse: payload,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function normalizeDeepgramWords(input) {
|
|
129
|
+
if (!Array.isArray(input))
|
|
130
|
+
return undefined;
|
|
131
|
+
const words = input
|
|
132
|
+
.filter((word) => typeof word === 'object' && word !== null)
|
|
133
|
+
.map((word) => {
|
|
134
|
+
const value = word;
|
|
135
|
+
return {
|
|
136
|
+
word: typeof value.punctuated_word === 'string'
|
|
137
|
+
? value.punctuated_word
|
|
138
|
+
: typeof value.word === 'string'
|
|
139
|
+
? value.word
|
|
140
|
+
: '',
|
|
141
|
+
start: typeof value.start === 'number' ? value.start : 0,
|
|
142
|
+
end: typeof value.end === 'number' ? value.end : 0,
|
|
143
|
+
confidence: typeof value.confidence === 'number' ? value.confidence : undefined,
|
|
144
|
+
speaker: typeof value.speaker === 'string' || typeof value.speaker === 'number'
|
|
145
|
+
? value.speaker
|
|
146
|
+
: undefined,
|
|
147
|
+
};
|
|
148
|
+
})
|
|
149
|
+
.filter((word) => word.word.length > 0);
|
|
150
|
+
return words.length > 0 ? words : undefined;
|
|
151
|
+
}
|
|
152
|
+
function normalizeDeepgramSegments(payload) {
|
|
153
|
+
const results = typeof payload.results === 'object' && payload.results !== null
|
|
154
|
+
? payload.results
|
|
155
|
+
: undefined;
|
|
156
|
+
if (results && Array.isArray(results.utterances) && results.utterances.length > 0) {
|
|
157
|
+
const utterances = results.utterances
|
|
158
|
+
.filter((utterance) => typeof utterance === 'object' && utterance !== null)
|
|
159
|
+
.map((utterance) => {
|
|
160
|
+
const value = utterance;
|
|
161
|
+
return {
|
|
162
|
+
text: typeof value.transcript === 'string' ? value.transcript : '',
|
|
163
|
+
start: typeof value.start === 'number' ? value.start : 0,
|
|
164
|
+
end: typeof value.end === 'number' ? value.end : 0,
|
|
165
|
+
confidence: typeof value.confidence === 'number' ? value.confidence : undefined,
|
|
166
|
+
speaker: typeof value.speaker === 'string' || typeof value.speaker === 'number'
|
|
167
|
+
? value.speaker
|
|
168
|
+
: undefined,
|
|
169
|
+
words: normalizeDeepgramWords(value.words),
|
|
170
|
+
};
|
|
171
|
+
})
|
|
172
|
+
.filter((segment) => segment.text.length > 0);
|
|
173
|
+
return utterances.length > 0 ? utterances : undefined;
|
|
174
|
+
}
|
|
175
|
+
const channels = results?.channels;
|
|
176
|
+
if (!Array.isArray(channels) || channels.length === 0)
|
|
177
|
+
return undefined;
|
|
178
|
+
const firstChannel = channels[0];
|
|
179
|
+
if (typeof firstChannel !== 'object' || firstChannel === null)
|
|
180
|
+
return undefined;
|
|
181
|
+
const alternatives = firstChannel.alternatives;
|
|
182
|
+
if (!Array.isArray(alternatives) || alternatives.length === 0)
|
|
183
|
+
return undefined;
|
|
184
|
+
const firstAlt = alternatives[0];
|
|
185
|
+
if (typeof firstAlt !== 'object' || firstAlt === null)
|
|
186
|
+
return undefined;
|
|
187
|
+
const alt = firstAlt;
|
|
188
|
+
const words = normalizeDeepgramWords(alt.words);
|
|
189
|
+
const start = words?.[0]?.start ?? 0;
|
|
190
|
+
const end = words?.[words.length - 1]?.end ?? 0;
|
|
191
|
+
const text = typeof alt.transcript === 'string' ? alt.transcript : '';
|
|
192
|
+
if (!text)
|
|
193
|
+
return undefined;
|
|
194
|
+
return [
|
|
195
|
+
{
|
|
196
|
+
text,
|
|
197
|
+
start,
|
|
198
|
+
end,
|
|
199
|
+
confidence: typeof alt.confidence === 'number' ? alt.confidence : undefined,
|
|
200
|
+
words,
|
|
201
|
+
},
|
|
202
|
+
];
|
|
203
|
+
}
|
|
204
|
+
class OpenAiBackend {
|
|
205
|
+
provider = 'openai';
|
|
206
|
+
isConfigured(config) {
|
|
207
|
+
return Boolean(config.openaiApiKey);
|
|
208
|
+
}
|
|
209
|
+
async transcribe(audio, input, config) {
|
|
210
|
+
const model = input.model || 'whisper-1';
|
|
211
|
+
const response = await fetch(`${stripTrailingSlash(config.openaiBaseUrl)}/audio/transcriptions`, {
|
|
212
|
+
method: 'POST',
|
|
213
|
+
headers: {
|
|
214
|
+
Authorization: `Bearer ${config.openaiApiKey}`,
|
|
215
|
+
},
|
|
216
|
+
body: buildOpenAiFormData(audio, input, model),
|
|
217
|
+
});
|
|
218
|
+
if (!response.ok) {
|
|
219
|
+
const message = await response.text();
|
|
220
|
+
throw new Error(`OpenAI Whisper transcription failed (${response.status}): ${message}`);
|
|
221
|
+
}
|
|
222
|
+
return parseOpenAiLikeResponse(response, input, 'openai', model);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
class WhisperLocalBackend {
|
|
226
|
+
provider = 'whisper-local';
|
|
227
|
+
isConfigured(config) {
|
|
228
|
+
return Boolean(config.whisperLocalBaseUrl);
|
|
229
|
+
}
|
|
230
|
+
async transcribe(audio, input, config) {
|
|
231
|
+
const baseUrl = config.whisperLocalBaseUrl || DEFAULT_WHISPER_LOCAL_BASE_URL;
|
|
232
|
+
const model = input.model || 'base';
|
|
233
|
+
const response = await fetch(`${stripTrailingSlash(baseUrl)}/audio/transcriptions`, {
|
|
234
|
+
method: 'POST',
|
|
235
|
+
body: buildOpenAiFormData(audio, input, model),
|
|
236
|
+
});
|
|
237
|
+
if (!response.ok) {
|
|
238
|
+
const message = await response.text();
|
|
239
|
+
throw new Error(`Whisper-local transcription failed (${response.status}): ${message}. ` +
|
|
240
|
+
'Ensure your local STT server exposes an OpenAI-compatible /audio/transcriptions endpoint.');
|
|
241
|
+
}
|
|
242
|
+
return parseOpenAiLikeResponse(response, input, 'whisper-local', model);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
class DeepgramBackend {
|
|
246
|
+
provider = 'deepgram';
|
|
247
|
+
isConfigured(config) {
|
|
248
|
+
return Boolean(config.deepgramApiKey);
|
|
249
|
+
}
|
|
250
|
+
async transcribe(audio, input, config) {
|
|
251
|
+
const model = input.model || 'nova-2';
|
|
252
|
+
const params = new URLSearchParams({
|
|
253
|
+
model,
|
|
254
|
+
smart_format: String(input.smartFormat ?? true),
|
|
255
|
+
punctuate: 'true',
|
|
256
|
+
utterances: String(input.utterances ?? true),
|
|
257
|
+
diarize: String(input.diarize ?? false),
|
|
258
|
+
});
|
|
259
|
+
if (input.language)
|
|
260
|
+
params.set('language', input.language);
|
|
261
|
+
if (input.detectLanguage)
|
|
262
|
+
params.set('detect_language', 'true');
|
|
263
|
+
if (input.prompt)
|
|
264
|
+
params.set('keywords', input.prompt);
|
|
265
|
+
const response = await fetch(`${stripTrailingSlash(config.deepgramBaseUrl)}/listen?${params.toString()}`, {
|
|
266
|
+
method: 'POST',
|
|
267
|
+
headers: {
|
|
268
|
+
Authorization: `Token ${config.deepgramApiKey}`,
|
|
269
|
+
'Content-Type': audio.mimeType,
|
|
270
|
+
},
|
|
271
|
+
body: audio.data,
|
|
272
|
+
});
|
|
273
|
+
if (!response.ok) {
|
|
274
|
+
const message = await response.text();
|
|
275
|
+
throw new Error(`Deepgram transcription failed (${response.status}): ${message}`);
|
|
276
|
+
}
|
|
277
|
+
const payload = (await response.json());
|
|
278
|
+
const results = typeof payload.results === 'object' && payload.results !== null
|
|
279
|
+
? payload.results
|
|
280
|
+
: {};
|
|
281
|
+
const channels = Array.isArray(results.channels) ? results.channels : [];
|
|
282
|
+
const firstChannel = channels.length > 0 && typeof channels[0] === 'object' && channels[0] !== null
|
|
283
|
+
? channels[0]
|
|
284
|
+
: undefined;
|
|
285
|
+
const alternatives = Array.isArray(firstChannel?.alternatives) ? firstChannel.alternatives : [];
|
|
286
|
+
const firstAlt = alternatives.length > 0 && typeof alternatives[0] === 'object' && alternatives[0] !== null
|
|
287
|
+
? alternatives[0]
|
|
288
|
+
: undefined;
|
|
289
|
+
const transcript = typeof firstAlt?.transcript === 'string' ? firstAlt.transcript : '';
|
|
290
|
+
const metadata = typeof payload.metadata === 'object' && payload.metadata !== null
|
|
291
|
+
? payload.metadata
|
|
292
|
+
: {};
|
|
293
|
+
const language = typeof firstAlt?.detected_language === 'string'
|
|
294
|
+
? firstAlt.detected_language
|
|
295
|
+
: typeof firstChannel?.detected_language === 'string'
|
|
296
|
+
? firstChannel.detected_language
|
|
297
|
+
: input.language;
|
|
298
|
+
return {
|
|
299
|
+
text: transcript,
|
|
300
|
+
provider: 'deepgram',
|
|
301
|
+
model,
|
|
302
|
+
language,
|
|
303
|
+
confidence: typeof firstAlt?.confidence === 'number' ? firstAlt.confidence : undefined,
|
|
304
|
+
durationSeconds: typeof metadata.duration === 'number' ? metadata.duration : undefined,
|
|
305
|
+
segments: normalizeDeepgramSegments(payload),
|
|
306
|
+
providerResponse: payload,
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const STT_BACKENDS = {
|
|
311
|
+
openai: new OpenAiBackend(),
|
|
312
|
+
deepgram: new DeepgramBackend(),
|
|
313
|
+
'whisper-local': new WhisperLocalBackend(),
|
|
314
|
+
};
|
|
315
|
+
export class SpeechToTextTool {
|
|
316
|
+
id = 'stt-multi-provider-v1';
|
|
317
|
+
name = 'speech_to_text';
|
|
318
|
+
displayName = 'Speech to Text';
|
|
319
|
+
description = 'Transcribe audio into text. Supports OpenAI Whisper, Deepgram, and Whisper-local/OpenAI-compatible local STT runtimes. ' +
|
|
320
|
+
'Accepts either base64 audio or a fetchable audio URL.';
|
|
321
|
+
category = 'media';
|
|
322
|
+
version = '2.0.0';
|
|
323
|
+
hasSideEffects = false;
|
|
324
|
+
requiredCapabilities = ['capability:stt'];
|
|
325
|
+
inputSchema = {
|
|
326
|
+
type: 'object',
|
|
327
|
+
properties: {
|
|
328
|
+
audioBase64: {
|
|
329
|
+
type: 'string',
|
|
330
|
+
description: 'Base64 audio payload. May be raw base64 or a data URL.',
|
|
331
|
+
},
|
|
332
|
+
audioUrl: {
|
|
333
|
+
type: 'string',
|
|
334
|
+
description: 'Fetchable remote audio URL. Used when audio is not provided inline.',
|
|
335
|
+
},
|
|
336
|
+
mimeType: {
|
|
337
|
+
type: 'string',
|
|
338
|
+
description: 'Optional MIME type override, such as audio/wav or audio/mpeg.',
|
|
339
|
+
},
|
|
340
|
+
fileName: {
|
|
341
|
+
type: 'string',
|
|
342
|
+
description: 'Optional filename sent to transcription providers.',
|
|
343
|
+
},
|
|
344
|
+
format: {
|
|
345
|
+
type: 'string',
|
|
346
|
+
description: 'Optional audio format hint, such as wav, mp3, m4a, or webm.',
|
|
347
|
+
},
|
|
348
|
+
language: {
|
|
349
|
+
type: 'string',
|
|
350
|
+
description: 'Optional ISO language hint, for example en or es.',
|
|
351
|
+
},
|
|
352
|
+
prompt: {
|
|
353
|
+
type: 'string',
|
|
354
|
+
description: 'Optional context prompt to bias the transcript.',
|
|
355
|
+
},
|
|
356
|
+
temperature: {
|
|
357
|
+
type: 'number',
|
|
358
|
+
minimum: 0,
|
|
359
|
+
maximum: 1,
|
|
360
|
+
description: 'Temperature override for Whisper-style providers.',
|
|
361
|
+
},
|
|
362
|
+
responseFormat: {
|
|
363
|
+
type: 'string',
|
|
364
|
+
enum: ['json', 'text', 'srt', 'verbose_json', 'vtt'],
|
|
365
|
+
description: 'Response format for OpenAI-compatible providers.',
|
|
366
|
+
},
|
|
367
|
+
provider: {
|
|
368
|
+
type: 'string',
|
|
369
|
+
enum: ['auto', 'openai', 'deepgram', 'whisper-local'],
|
|
370
|
+
description: 'STT provider selection. Default: auto.',
|
|
371
|
+
},
|
|
372
|
+
model: {
|
|
373
|
+
type: 'string',
|
|
374
|
+
description: 'Provider model override. Examples: whisper-1, nova-2, base.',
|
|
375
|
+
},
|
|
376
|
+
diarize: {
|
|
377
|
+
type: 'boolean',
|
|
378
|
+
description: 'Enable speaker diarization when the provider supports it.',
|
|
379
|
+
},
|
|
380
|
+
utterances: {
|
|
381
|
+
type: 'boolean',
|
|
382
|
+
description: 'Request utterance segmentation when the provider supports it.',
|
|
383
|
+
},
|
|
384
|
+
smartFormat: {
|
|
385
|
+
type: 'boolean',
|
|
386
|
+
description: 'Enable provider-side smart formatting where supported.',
|
|
387
|
+
},
|
|
388
|
+
detectLanguage: {
|
|
389
|
+
type: 'boolean',
|
|
390
|
+
description: 'Enable provider-side language detection where supported.',
|
|
391
|
+
},
|
|
392
|
+
providerOptions: {
|
|
393
|
+
type: 'object',
|
|
394
|
+
description: 'Optional provider-specific passthrough options for future-compatible callers.',
|
|
395
|
+
additionalProperties: true,
|
|
396
|
+
},
|
|
397
|
+
},
|
|
398
|
+
required: [],
|
|
399
|
+
};
|
|
400
|
+
config;
|
|
401
|
+
constructor(config) {
|
|
402
|
+
this.config = {
|
|
403
|
+
openaiApiKey: config?.openaiApiKey || process.env.OPENAI_API_KEY || undefined,
|
|
404
|
+
openaiBaseUrl: stripTrailingSlash(config?.openaiBaseUrl || process.env.OPENAI_BASE_URL || DEFAULT_OPENAI_BASE_URL),
|
|
405
|
+
deepgramApiKey: config?.deepgramApiKey || process.env.DEEPGRAM_API_KEY || undefined,
|
|
406
|
+
deepgramBaseUrl: stripTrailingSlash(config?.deepgramBaseUrl || process.env.DEEPGRAM_BASE_URL || DEFAULT_DEEPGRAM_BASE_URL),
|
|
407
|
+
whisperLocalBaseUrl: config?.whisperLocalBaseUrl || process.env.WHISPER_LOCAL_BASE_URL || undefined,
|
|
408
|
+
defaultProvider: config?.defaultProvider || process.env.STT_PROVIDER || 'auto',
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
resolveProvider(requested) {
|
|
412
|
+
const preferred = requested || this.config.defaultProvider || 'auto';
|
|
413
|
+
if (preferred !== 'auto') {
|
|
414
|
+
if (preferred === 'whisper-local')
|
|
415
|
+
return 'whisper-local';
|
|
416
|
+
return STT_BACKENDS[preferred].isConfigured(this.config) ? preferred : null;
|
|
417
|
+
}
|
|
418
|
+
if (STT_BACKENDS.openai.isConfigured(this.config))
|
|
419
|
+
return 'openai';
|
|
420
|
+
if (STT_BACKENDS.deepgram.isConfigured(this.config))
|
|
421
|
+
return 'deepgram';
|
|
422
|
+
if (STT_BACKENDS['whisper-local'].isConfigured(this.config))
|
|
423
|
+
return 'whisper-local';
|
|
424
|
+
return null;
|
|
425
|
+
}
|
|
426
|
+
async prepareAudio(input) {
|
|
427
|
+
if (typeof input.audioBase64 === 'string' && input.audioBase64.trim()) {
|
|
428
|
+
const normalized = normalizeBase64Input(input.audioBase64);
|
|
429
|
+
const mimeType = input.mimeType || normalized.mimeType || 'audio/wav';
|
|
430
|
+
const format = input.format || extensionFromMimeType(mimeType);
|
|
431
|
+
return {
|
|
432
|
+
data: normalized.data,
|
|
433
|
+
mimeType,
|
|
434
|
+
format,
|
|
435
|
+
fileName: input.fileName || `audio.${format}`,
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
if (typeof input.audioUrl === 'string' && input.audioUrl.trim()) {
|
|
439
|
+
const response = await fetch(input.audioUrl);
|
|
440
|
+
if (!response.ok) {
|
|
441
|
+
throw new Error(`Audio download failed (${response.status})`);
|
|
442
|
+
}
|
|
443
|
+
const mimeType = input.mimeType || response.headers.get('content-type') || 'audio/wav';
|
|
444
|
+
const format = input.format || extensionFromMimeType(mimeType);
|
|
445
|
+
return {
|
|
446
|
+
data: Buffer.from(await response.arrayBuffer()),
|
|
447
|
+
mimeType,
|
|
448
|
+
format,
|
|
449
|
+
fileName: input.fileName || `audio.${format}`,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
throw new Error('Provide either audioBase64 or audioUrl.');
|
|
453
|
+
}
|
|
454
|
+
async execute(args, _context) {
|
|
455
|
+
try {
|
|
456
|
+
const provider = this.resolveProvider(args.provider);
|
|
457
|
+
if (!provider) {
|
|
458
|
+
return {
|
|
459
|
+
success: false,
|
|
460
|
+
error: 'No STT provider available. Configure OPENAI_API_KEY, DEEPGRAM_API_KEY, or WHISPER_LOCAL_BASE_URL. ' +
|
|
461
|
+
'You can also explicitly set provider to "whisper-local" to target a local OpenAI-compatible STT server.',
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
const audio = await this.prepareAudio(args);
|
|
465
|
+
const output = await STT_BACKENDS[provider].transcribe(audio, args, this.config);
|
|
466
|
+
return {
|
|
467
|
+
success: true,
|
|
468
|
+
output,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
catch (error) {
|
|
472
|
+
return {
|
|
473
|
+
success: false,
|
|
474
|
+
error: error instanceof Error ? error.message : String(error),
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
//# sourceMappingURL=speechToText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speechToText.js","sourceRoot":"","sources":["../../src/tools/speechToText.ts"],"names":[],"mappings":"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"}
|
package/manifest.json
CHANGED
|
@@ -2,19 +2,34 @@
|
|
|
2
2
|
"$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
|
|
3
3
|
"id": "com.framers.media.voice-synthesis",
|
|
4
4
|
"name": "Voice Synthesis Extension",
|
|
5
|
-
"version": "
|
|
6
|
-
"description": "
|
|
5
|
+
"version": "2.0.0",
|
|
6
|
+
"description": "Voice synthesis and transcription tools via OpenAI, ElevenLabs, Deepgram, and local Ollama/Whisper-compatible runtimes",
|
|
7
7
|
"author": { "name": "Frame.dev" },
|
|
8
8
|
"license": "MIT",
|
|
9
|
-
"keywords": ["tts", "voice", "speech", "elevenlabs", "audio"],
|
|
9
|
+
"keywords": ["tts", "stt", "voice", "speech", "transcription", "openai", "elevenlabs", "deepgram", "ollama", "whisper", "audio"],
|
|
10
10
|
"agentosVersion": "^2.0.0",
|
|
11
11
|
"categories": ["media", "communication"],
|
|
12
12
|
"extensions": [
|
|
13
|
-
{ "kind": "tool", "id": "text_to_speech", "displayName": "Text to Speech", "entry": "./dist/tools/textToSpeech.js" }
|
|
13
|
+
{ "kind": "tool", "id": "text_to_speech", "displayName": "Text to Speech", "entry": "./dist/tools/textToSpeech.js" },
|
|
14
|
+
{ "kind": "tool", "id": "speech_to_text", "displayName": "Speech to Text", "entry": "./dist/tools/speechToText.js" }
|
|
14
15
|
],
|
|
15
16
|
"configuration": {
|
|
16
17
|
"properties": {
|
|
17
|
-
"
|
|
18
|
+
"openai.apiKey": { "type": "string", "secret": true },
|
|
19
|
+
"openai.baseUrl": { "type": "string" },
|
|
20
|
+
"deepgram.apiKey": { "type": "string", "secret": true },
|
|
21
|
+
"deepgram.baseUrl": { "type": "string" },
|
|
22
|
+
"elevenlabs.apiKey": { "type": "string", "secret": true },
|
|
23
|
+
"ollama.baseUrl": { "type": "string" },
|
|
24
|
+
"whisperLocal.baseUrl": { "type": "string" },
|
|
25
|
+
"tts.defaultProvider": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"enum": ["auto", "openai", "elevenlabs", "ollama"]
|
|
28
|
+
},
|
|
29
|
+
"stt.defaultProvider": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"enum": ["auto", "openai", "deepgram", "whisper-local"]
|
|
32
|
+
}
|
|
18
33
|
}
|
|
19
34
|
}
|
|
20
35
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@framers/agentos-ext-voice-synthesis",
|
|
3
|
-
"version": "2.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"description": "Voice synthesis and transcription tools for AgentOS via OpenAI, ElevenLabs, Deepgram, and local Ollama/Whisper-compatible runtimes",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
@@ -18,10 +18,14 @@
|
|
|
18
18
|
"agentos",
|
|
19
19
|
"extension",
|
|
20
20
|
"tts",
|
|
21
|
+
"stt",
|
|
21
22
|
"voice",
|
|
23
|
+
"transcription",
|
|
22
24
|
"openai",
|
|
23
25
|
"elevenlabs",
|
|
26
|
+
"deepgram",
|
|
24
27
|
"ollama",
|
|
28
|
+
"whisper",
|
|
25
29
|
"speech",
|
|
26
30
|
"media"
|
|
27
31
|
],
|
package/src/index.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Voice Synthesis Extension Pack —
|
|
2
|
+
* Voice Synthesis Extension Pack — TTS + STT voice tools for agents.
|
|
3
3
|
*
|
|
4
|
-
* Supports: OpenAI TTS, ElevenLabs, Ollama (local).
|
|
4
|
+
* Supports: OpenAI TTS/STT, ElevenLabs TTS, Ollama (local TTS).
|
|
5
5
|
* Auto-detects available provider from API keys.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { TextToSpeechTool, type TTSConfig, type TTSProvider } from './tools/textToSpeech.js';
|
|
9
|
+
import { SpeechToTextTool, type STTConfig, type STTProvider } from './tools/speechToText.js';
|
|
9
10
|
|
|
10
11
|
export interface VoiceSynthesisExtensionOptions {
|
|
11
12
|
elevenLabsApiKey?: string;
|
|
12
13
|
openaiApiKey?: string;
|
|
13
14
|
openaiBaseUrl?: string;
|
|
15
|
+
deepgramApiKey?: string;
|
|
16
|
+
deepgramBaseUrl?: string;
|
|
14
17
|
ollamaBaseUrl?: string;
|
|
18
|
+
whisperLocalBaseUrl?: string;
|
|
15
19
|
defaultProvider?: TTSProvider;
|
|
20
|
+
defaultSttProvider?: STTProvider;
|
|
16
21
|
priority?: number;
|
|
17
22
|
}
|
|
18
23
|
|
|
@@ -26,29 +31,53 @@ export function createExtensionPack(context: any) {
|
|
|
26
31
|
ollamaBaseUrl: options.ollamaBaseUrl || process.env.OLLAMA_BASE_URL,
|
|
27
32
|
defaultProvider: options.defaultProvider || (process.env.TTS_PROVIDER as TTSProvider) || 'auto',
|
|
28
33
|
};
|
|
34
|
+
const sttConfig: STTConfig = {
|
|
35
|
+
openaiApiKey: options.openaiApiKey || context.getSecret?.('openai.apiKey') || process.env.OPENAI_API_KEY,
|
|
36
|
+
openaiBaseUrl: options.openaiBaseUrl || process.env.OPENAI_BASE_URL,
|
|
37
|
+
deepgramApiKey: options.deepgramApiKey || context.getSecret?.('deepgram.apiKey') || process.env.DEEPGRAM_API_KEY,
|
|
38
|
+
deepgramBaseUrl: options.deepgramBaseUrl || process.env.DEEPGRAM_BASE_URL,
|
|
39
|
+
whisperLocalBaseUrl: options.whisperLocalBaseUrl || process.env.WHISPER_LOCAL_BASE_URL,
|
|
40
|
+
defaultProvider: options.defaultSttProvider || (process.env.STT_PROVIDER as STTProvider) || 'auto',
|
|
41
|
+
};
|
|
29
42
|
|
|
30
|
-
const
|
|
43
|
+
const ttsTool = new TextToSpeechTool(config);
|
|
44
|
+
const sttTool = new SpeechToTextTool(sttConfig);
|
|
31
45
|
|
|
32
|
-
// Determine which providers are available for the activation message
|
|
33
46
|
const providers: string[] = [];
|
|
34
47
|
if (config.openaiApiKey) providers.push('OpenAI');
|
|
35
48
|
if (config.elevenLabsApiKey) providers.push('ElevenLabs');
|
|
36
49
|
providers.push('Ollama (local fallback)');
|
|
50
|
+
const sttProviders: string[] = [];
|
|
51
|
+
if (sttConfig.openaiApiKey) sttProviders.push('OpenAI Whisper');
|
|
52
|
+
if (sttConfig.deepgramApiKey) sttProviders.push('Deepgram');
|
|
53
|
+
if (sttConfig.whisperLocalBaseUrl) sttProviders.push('Whisper-local');
|
|
54
|
+
|
|
55
|
+
const features: string[] = [
|
|
56
|
+
`TTS: ${providers.join(', ')}`,
|
|
57
|
+
`STT: ${sttProviders.length > 0 ? sttProviders.join(', ') : 'not configured'}`,
|
|
58
|
+
];
|
|
37
59
|
|
|
38
60
|
return {
|
|
39
61
|
name: '@framers/agentos-ext-voice-synthesis',
|
|
40
62
|
version: '2.0.0',
|
|
41
63
|
descriptors: [
|
|
42
64
|
{
|
|
43
|
-
id:
|
|
65
|
+
id: ttsTool.name,
|
|
66
|
+
kind: 'tool' as const,
|
|
67
|
+
priority: options.priority || 50,
|
|
68
|
+
payload: ttsTool,
|
|
69
|
+
requiredSecrets: [],
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: sttTool.name,
|
|
44
73
|
kind: 'tool' as const,
|
|
45
74
|
priority: options.priority || 50,
|
|
46
|
-
payload:
|
|
75
|
+
payload: sttTool,
|
|
47
76
|
requiredSecrets: [],
|
|
48
77
|
},
|
|
49
78
|
],
|
|
50
79
|
onActivate: async () => {
|
|
51
|
-
context.logger?.info?.(`Voice Synthesis activated —
|
|
80
|
+
context.logger?.info?.(`Voice Synthesis activated — ${features.join(' | ')}`);
|
|
52
81
|
},
|
|
53
82
|
onDeactivate: async () => {
|
|
54
83
|
context.logger?.info?.('Voice Synthesis deactivated');
|
|
@@ -57,5 +86,7 @@ export function createExtensionPack(context: any) {
|
|
|
57
86
|
}
|
|
58
87
|
|
|
59
88
|
export { TextToSpeechTool };
|
|
89
|
+
export { SpeechToTextTool };
|
|
60
90
|
export type { TTSInput, TTSOutput, TTSConfig, TTSProvider } from './tools/textToSpeech.js';
|
|
91
|
+
export type { STTInput, STTOutput, STTConfig, STTProvider } from './tools/speechToText.js';
|
|
61
92
|
export default createExtensionPack;
|