Compare commits

...

13 Commits

Author SHA1 Message Date
Hoan Luu Huu
1d609135fc support trunk_types in voip_carriers (#496)
* support trunk_types in voip_carriers

* wip

* wip

* wip
2025-10-21 06:47:56 -04:00
Dan Jenkins
16dcd26216 allow disabling of all rate limits (#505) 2025-10-20 10:58:34 -04:00
Hoan Luu Huu
42f4318a17 support gladia stt (#503)
* support gladia stt

* wip

* update verb specification
2025-10-20 04:47:17 -04:00
Sam Machin
0f1f5e9b73 bump dbhelpers for cache change (#504) 2025-10-15 11:38:07 -04:00
Hoan Luu Huu
bcff9b35a6 support houndify stt (#498)
* support houndify stt

* wip

* test houdify stt credential

* wip

* wip

* update verb specification
2025-10-14 00:52:49 -04:00
Hoan Luu Huu
8267ddaffd support elevenlabs different endpoint (#502)
* support elevenlabs different endpoint

* wip

* wip

* wip
2025-10-09 08:20:11 -04:00
Hoan Luu Huu
c3d12fafee support deeepgram influx (#501)
* support deeepgram influx

* update verb specification
2025-10-03 10:09:19 -04:00
Hoan Luu Huu
9421bb8aa1 fixed deepgram cannot fetch list of available voices for model (#500) 2025-09-27 10:13:06 -04:00
Hoan Luu Huu
a15c5cd267 speech utils v0.2.23 (#497) 2025-09-11 01:30:12 -04:00
Dave Horton
4de66789ef fix db upgrade script (#495) 2025-09-07 10:58:14 -04:00
RJ Burnham
a297d2038f Refactor S3MultipartUploadStream to optimize buffer handling and improve upload efficiency (#494)
- Replaced Buffer.concat with chunk accumulation to reduce time complexity during writes.
- Introduced bufferedBytes to track total size of accumulated chunks.
- Updated upload logic to handle parts more efficiently, minimizing memory overhead.
- Enhanced logging in upload function to include selected encoder format for better traceability.

(cherry picked from commit ce8bba2f18d807d4872b168e451e4501b1acb824)
2025-09-04 07:34:19 -04:00
Sam Machin
2e0ea56925 Fix API for Carriers & SIP Gateways (#492)
* allow account api keys to get/post sip gateways

* require sp sid when creating carriers

* allow account level api keys to query carriers

* lookup and set the service_provider_sid on account create carrier
2025-08-28 08:46:42 -04:00
Dave Horton
9c8bfebd53 update to latest speech-utils 2025-08-17 09:53:33 -04:00
18 changed files with 1163 additions and 196 deletions

View File

@@ -35,6 +35,7 @@ Configuration is provided via environment variables:
|K8S_FEATURE_SERVER_SERVICE_PORT| feature server port(required for K8S) |no|
|JAMBONZ_RECORD_WS_USERNAME| recording websocket username|no|
|JAMBONZ_RECORD_WS_PASSWORD| recording websocket password|no|
|DISABLE_RATE_LIMITS| disable rate limiting|no
#### Database dependency
A mysql database is used to store long-lived objects such as Accounts, Applications, etc. To create the database schema, use or review the scripts in the 'db' folder, particularly:

7
app.js
View File

@@ -170,7 +170,12 @@ if (process.env.JAMBONES_TRUST_PROXY) {
});
}
}
app.use(limiter);
const disableRateLimit = process.env.DISABLE_RATE_LIMITS === 'true' || process.env.DISABLE_RATE_LIMITS === '1';
if (!disableRateLimit) {
app.use(limiter);
}
app.use(helmet());
app.use(helmet.hidePoweredBy());
app.use(nocache());

View File

@@ -1,5 +1,4 @@
/* SQLEditor (MySQL (2))*/
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS account_static_ips;
@@ -418,6 +417,7 @@ register_public_ip_in_contact BOOLEAN NOT NULL DEFAULT false,
register_status VARCHAR(4096),
dtmf_type ENUM('rfc2833','tones','info') NOT NULL DEFAULT 'rfc2833',
outbound_sip_proxy VARCHAR(255),
trunk_type ENUM('static_ip','auth','reg') NOT NULL DEFAULT 'static_ip',
PRIMARY KEY (voip_carrier_sid)
) COMMENT='A Carrier or customer PBX that can send or receive calls';

View File

@@ -546,12 +546,12 @@
<schema><![CDATA[]]></schema>
<comment><![CDATA[A Carrier or customer PBX that can send or receive calls]]></comment>
<location>
<x>16.00</x>
<y>427.00</y>
<x>20.00</x>
<y>418.00</y>
</location>
<size>
<width>293.00</width>
<height>580.00</height>
<height>600.00</height>
</size>
<zorder>6</zorder>
<SQLField>
@@ -749,6 +749,13 @@
<type><![CDATA[VARCHAR(255)]]></type>
<uid><![CDATA[556ABA45-BC63-444D-8CB1-973EFCCF9FE7]]></uid>
</SQLField>
<SQLField>
<name><![CDATA[trunk_type]]></name>
<type><![CDATA[ENUM('static_ip','auth','reg')]]></type>
<defaultValue><![CDATA[static_ip]]></defaultValue>
<notNull><![CDATA[1]]></notNull>
<uid><![CDATA[CCF1560C-349E-4DB9-91E5-120F1EDB7CDE]]></uid>
</SQLField>
<labelWindowIndex><![CDATA[28]]></labelWindowIndex>
<objectComment><![CDATA[A Carrier or customer PBX that can send or receive calls]]></objectComment>
<ui.treeExpanded><![CDATA[1]]></ui.treeExpanded>
@@ -1293,7 +1300,7 @@
<comment><![CDATA[a regex-based pattern match for call routing]]></comment>
<location>
<x>16.00</x>
<y>1007.00</y>
<y>1039.00</y>
</location>
<size>
<width>254.00</width>
@@ -2165,8 +2172,8 @@
<schema><![CDATA[]]></schema>
<comment><![CDATA[A phone number that has been assigned to an account]]></comment>
<location>
<x>16.00</x>
<y>1128.00</y>
<x>11.00</x>
<y>1162.00</y>
</location>
<size>
<width>522.00</width>
@@ -2608,6 +2615,7 @@
<SQLField>
<name><![CDATA[speech_synthesis_voice]]></name>
<type><![CDATA[VARCHAR(256)]]></type>
<defaultValue><![CDATA[en-US-Standard-C]]></defaultValue>
<notNull><![CDATA[0]]></notNull>
<uid><![CDATA[929D66F0-64B9-4D7C-AB4B-24F131E1178F]]></uid>
</SQLField>
@@ -3161,17 +3169,17 @@
<overviewPanelHidden><![CDATA[0]]></overviewPanelHidden>
<pageBoundariesVisible><![CDATA[0]]></pageBoundariesVisible>
<PageGridVisible><![CDATA[0]]></PageGridVisible>
<RightSidebarWidth><![CDATA[1393.000000]]></RightSidebarWidth>
<RightSidebarWidth><![CDATA[1643.000000]]></RightSidebarWidth>
<sidebarIndex><![CDATA[2]]></sidebarIndex>
<snapToGrid><![CDATA[0]]></snapToGrid>
<SourceSidebarWidth><![CDATA[0.000000]]></SourceSidebarWidth>
<SourceSidebarWidth><![CDATA[312.000000]]></SourceSidebarWidth>
<SQLEditorFileFormatVersion><![CDATA[4]]></SQLEditorFileFormatVersion>
<uid><![CDATA[58C99A00-06C9-478C-A667-C63842E088F3]]></uid>
<windowHeight><![CDATA[1055.000000]]></windowHeight>
<windowLocationX><![CDATA[1845.000000]]></windowLocationX>
<windowLocationX><![CDATA[1728.000000]]></windowLocationX>
<windowLocationY><![CDATA[37.000000]]></windowLocationY>
<windowScrollOrigin><![CDATA[{0, 544}]]></windowScrollOrigin>
<windowWidth><![CDATA[1670.000000]]></windowWidth>
<windowScrollOrigin><![CDATA[{0, 376}]]></windowScrollOrigin>
<windowWidth><![CDATA[1920.000000]]></windowWidth>
</SQLDocumentInfo>
<AllowsIndexRenamingOnInsert><![CDATA[1]]></AllowsIndexRenamingOnInsert>
<defaultLabelExpanded><![CDATA[1]]></defaultLabelExpanded>

View File

@@ -231,7 +231,8 @@ const sql = {
],
9005: [
'UPDATE applications SET speech_synthesis_voice = \'en-US-Standard-C\' WHERE speech_synthesis_voice IS NULL AND speech_synthesis_vendor = \'google\' AND speech_synthesis_language = \'en-US\'',
'ALTER TABLE applications MODIFY COLUMN speech_synthesis_voice VARCHAR(255) DEFAULT \'en-US-Standard-C\''
'ALTER TABLE applications MODIFY COLUMN speech_synthesis_voice VARCHAR(255) DEFAULT \'en-US-Standard-C\'',
'ALTER TABLE voip_carriers ADD COLUMN trunk_type ENUM(\'static_ip\',\'auth\',\'reg\') NOT NULL DEFAULT \'static_ip\'',
]
};
@@ -267,6 +268,8 @@ const doIt = async() => {
if (val < 9000) upgrades.push(...sql['9000']);
if (val < 9002) upgrades.push(...sql['9002']);
if (val < 9003) upgrades.push(...sql['9003']);
if (val < 9004) upgrades.push(...sql['9004']);
if (val < 9005) upgrades.push(...sql['9005']);
// perform all upgrades
logger.info({upgrades}, 'applying schema upgrades..');

View File

@@ -15,7 +15,9 @@ class S3MultipartUploadStream extends Writable {
this.uploadId = null;
this.partNumber = 1;
this.multipartETags = [];
this.buffer = Buffer.alloc(0);
// accumulate incoming chunks to avoid O(n^2) Buffer.concat on every write
this.chunks = [];
this.bufferedBytes = 0;
this.minPartSize = 5 * 1024 * 1024; // 5 MB
this.s3 = new S3Client(opts.bucketCredential);
this.metadata = opts.metadata;
@@ -31,13 +33,13 @@ class S3MultipartUploadStream extends Writable {
return response.UploadId;
}
async _uploadBuffer() {
async _uploadPart(bodyBuffer) {
const uploadPartCommand = new UploadPartCommand({
Bucket: this.bucketName,
Key: this.objectKey,
PartNumber: this.partNumber,
UploadId: this.uploadId,
Body: this.buffer,
Body: bodyBuffer,
});
const uploadPartResponse = await this.s3.send(uploadPartCommand);
@@ -54,11 +56,16 @@ class S3MultipartUploadStream extends Writable {
this.uploadId = await this._initMultipartUpload();
}
this.buffer = Buffer.concat([this.buffer, chunk]);
// accumulate without concatenating on every write
this.chunks.push(chunk);
this.bufferedBytes += chunk.length;
if (this.buffer.length >= this.minPartSize) {
await this._uploadBuffer();
this.buffer = Buffer.alloc(0);
if (this.bufferedBytes >= this.minPartSize) {
const partBuffer = Buffer.concat(this.chunks, this.bufferedBytes);
// reset accumulators before awaiting upload to allow GC
this.chunks = [];
this.bufferedBytes = 0;
await this._uploadPart(partBuffer);
}
callback(null);
@@ -69,8 +76,11 @@ class S3MultipartUploadStream extends Writable {
async _finalize(err) {
try {
if (this.buffer.length > 0) {
await this._uploadBuffer();
if (this.bufferedBytes > 0) {
const finalBuffer = Buffer.concat(this.chunks, this.bufferedBytes);
this.chunks = [];
this.bufferedBytes = 0;
await this._uploadPart(finalBuffer);
}
const completeMultipartUploadCommand = new CompleteMultipartUploadCommand({

View File

@@ -51,8 +51,10 @@ async function upload(logger, socket) {
/**encoder */
let encoder;
let recordFormat;
if (account[0].record_format === 'wav') {
encoder = new wav.Writer({ channels: 2, sampleRate, bitDepth: 16 });
recordFormat = 'wav';
} else {
// default is mp3
encoder = new PCMToMP3Encoder({
@@ -60,7 +62,9 @@ async function upload(logger, socket) {
sampleRate: sampleRate,
bitrate: 128
}, logger);
recordFormat = 'mp3';
}
logger.info({ record_format: recordFormat, channels: 2, sampleRate }, 'record upload: selected encoder');
/* start streaming data */
pipeline(

View File

@@ -161,6 +161,9 @@ router.post('/:sid/VoipCarriers', async(req, res) => {
try {
const account_sid = parseAccountSid(req);
await validateRequest(req, account_sid);
// Set the service_provder_sid to the relevent value for the account
const account = await Account.retrieve(req.user.account_sid);
payload.service_provider_sid = account[0].service_provider_sid;
logger.debug({payload}, 'POST /:sid/VoipCarriers');
const uuid = await VoipCarrier.make({

View File

@@ -46,10 +46,16 @@ async function validateRetrieve(req) {
return;
}
if (req.user.hasScope('service_provider') || req.user.hasScope('account')) {
if (req.user.hasScope('service_provider')) {
if (service_provider_sid === req.user.service_provider_sid) return;
}
if (req.user.hasScope('account')) {
const results = await Account.retrieve(req.user.account_sid);
if (service_provider_sid === results[0].service_provider_sid) return;
}
throw new DbErrorForbidden('insufficient permissions');
} catch (error) {
throw error;

View File

@@ -18,8 +18,7 @@ const checkUserScope = async(req, voip_carrier_sid) => {
const carrier = await lookupCarrierBySid(voip_carrier_sid);
if (!carrier) throw new DbErrorBadRequest('invalid voip_carrier_sid');
if ((!carrier.service_provider_sid || carrier.service_provider_sid === req.user.service_provider_sid) &&
(!carrier.account_sid || carrier.account_sid === req.user.account_sid)) {
if (!carrier.account_sid || carrier.account_sid === req.user.account_sid) {
if (req.method !== 'GET' && !carrier.account_sid) {
throw new DbErrorForbidden('insufficient privileges');

View File

@@ -16,7 +16,9 @@ const {decryptCredential, testWhisper, testDeepgramTTS,
testVoxistStt,
testOpenAiStt,
testInworld,
testResembleTTS} = require('../../utils/speech-utils');
testResembleTTS,
testHoundifyStt,
testGladiaStt} = require('../../utils/speech-utils');
const {DbErrorUnprocessableRequest, DbErrorForbidden, DbErrorBadRequest} = require('../../utils/errors');
const {
testGoogleTts,
@@ -124,6 +126,7 @@ const encryptCredential = (obj) => {
role_arn,
region,
client_id,
client_key,
client_secret,
secret,
nuance_tts_uri,
@@ -162,6 +165,7 @@ const encryptCredential = (obj) => {
voice_engine,
engine_version,
service_version,
api_uri,
options
} = obj;
@@ -229,6 +233,10 @@ const encryptCredential = (obj) => {
deepgram_stt_use_tls, deepgram_tts_uri, model_id});
return encrypt(deepgramData);
case 'gladia':
const gladiaData = JSON.stringify({api_key, region});
return encrypt(gladiaData);
case 'resemble':
assert(api_key, 'invalid resemble speech credential: api_key is required');
const resembleData = JSON.stringify({
@@ -238,10 +246,10 @@ const encryptCredential = (obj) => {
});
return encrypt(resembleData);
case 'deepgramriver':
assert(api_key, 'invalid deepgram river speech credential: api_key is required');
const deepgramriverData = JSON.stringify({api_key});
return encrypt(deepgramriverData);
case 'deepgramflux':
assert(api_key, 'invalid deepgram flux speech credential: api_key is required');
const deepgramfluxData = JSON.stringify({api_key});
return encrypt(deepgramfluxData);
case 'ibm':
const ibmData = JSON.stringify({tts_api_key, tts_region, stt_api_key, stt_region, instance_id});
@@ -265,7 +273,11 @@ const encryptCredential = (obj) => {
case 'elevenlabs':
assert(api_key, 'invalid elevenLabs speech credential: api_key is required');
assert(model_id, 'invalid elevenLabs speech credential: model_id is required');
const elevenlabsData = JSON.stringify({api_key, model_id, options});
const elevenlabsData = JSON.stringify({
api_key,
model_id,
...(api_uri && {api_uri}),
options});
return encrypt(elevenlabsData);
case 'speechmatics':
@@ -313,6 +325,13 @@ const encryptCredential = (obj) => {
const assemblyaiData = JSON.stringify({api_key, service_version});
return encrypt(assemblyaiData);
case 'houndify':
assert(client_id, 'invalid houndify speech credential: client_id is required');
assert(client_key, 'invalid houndify speech credential: client_key is required');
assert(user_id, 'invalid houndify speech credential: user_id is required');
const houndifyData = JSON.stringify({client_id, client_key, user_id});
return encrypt(houndifyData);
case 'voxist':
assert(api_key, 'invalid voxist speech credential: api_key is required');
const voxistData = JSON.stringify({api_key});
@@ -537,7 +556,8 @@ router.put('/:sid', async(req, res) => {
service_version,
speechmatics_stt_uri,
resemble_tts_use_tls,
resemble_tts_uri
resemble_tts_uri,
api_uri
} = req.body;
const newCred = {
@@ -572,7 +592,8 @@ router.put('/:sid', async(req, res) => {
service_version,
speechmatics_stt_uri,
resemble_tts_uri,
resemble_tts_use_tls
resemble_tts_use_tls,
api_uri
};
logger.info({o, newCred}, 'updating speech credential with this new credential');
obj.credential = encryptCredential(newCred);
@@ -806,7 +827,7 @@ router.get('/:sid/test', async(req, res) => {
}
}
}
else if (cred.vendor === 'deepgramriver') {
else if (cred.vendor === 'deepgramflux') {
const {api_key} = credential;
if (cred.use_for_stt && api_key) {
try {
@@ -819,6 +840,18 @@ router.get('/:sid/test', async(req, res) => {
}
}
}
else if (cred.vendor === 'gladia') {
if (cred.use_for_stt) {
try {
await testGladiaStt(logger, credential);
results.stt.status = 'ok';
SpeechCredential.sttTestResult(sid, true);
} catch (err) {
results.stt = {status: 'fail', reason: err.message};
SpeechCredential.sttTestResult(sid, false);
}
}
}
else if (cred.vendor === 'ibm') {
const {getTtsVoices} = req.app.locals;
@@ -865,10 +898,10 @@ router.get('/:sid/test', async(req, res) => {
}
}
} else if (cred.vendor === 'elevenlabs') {
const {api_key, model_id} = credential;
const {api_key, model_id, api_uri} = credential;
if (cred.use_for_tts) {
try {
await testElevenlabs(logger, {api_key, model_id});
await testElevenlabs(logger, {api_key, model_id, api_uri});
results.tts.status = 'ok';
SpeechCredential.ttsTestResult(sid, true);
} catch (err) {
@@ -963,6 +996,17 @@ router.get('/:sid/test', async(req, res) => {
SpeechCredential.sttTestResult(sid, false);
}
}
} else if (cred.vendor === 'houndify') {
if (cred.use_for_stt) {
try {
await testHoundifyStt(logger, credential);
results.stt.status = 'ok';
SpeechCredential.sttTestResult(sid, true);
} catch (err) {
results.stt = {status: 'fail', reason: err.message};
SpeechCredential.sttTestResult(sid, false);
}
}
} else if (cred.vendor === 'voxist') {
const {api_key} = credential;
if (cred.use_for_stt) {

View File

@@ -1,56 +1,153 @@
module.exports = [
{ name: 'Multilingual', value: 'multi' },
{ name: 'Afrikaans', value: 'af' },
{ name: 'Amharic', value: 'am' },
{ name: 'Arabic', value: 'ar' },
{ name: 'Assamese', value: 'as' },
{ name: 'Azerbaijani', value: 'az' },
{ name: 'Bashkir', value: 'ba' },
{ name: 'Belarusian', value: 'be' },
{ name: 'Bulgarian', value: 'bg' },
{ name: 'Bengali', value: 'bn' },
{ name: 'Tibetan', value: 'bo' },
{ name: 'Breton', value: 'br' },
{ name: 'Bosnian', value: 'bs' },
{ name: 'Catalan', value: 'ca' },
{ name: 'Chinese (Mandarin, Simplified)', value: 'zh' },
{ name: 'Chinese (Mandarin, Simplified - China)', value: 'zh-CN' },
{ name: 'Chinese (Mandarin, Simplified - Hans)', value: 'zh-Hans' },
{ name: 'Chinese (Mandarin, Traditional)', value: 'zh-TW' },
{ name: 'Chinese (Mandarin, Traditional - Hant)', value: 'zh-Hant' },
{ name: 'Chinese (Cantonese, Traditional - Hong Kong)', value: 'zh-HK' },
{ name: 'Czech', value: 'cs' },
{ name: 'Welsh', value: 'cy' },
{ name: 'Danish', value: 'da' },
{ name: 'Danish (Denmark)', value: 'da-DK' },
{ name: 'Dutch', value: 'nl' },
{ name: 'English', value: 'en' },
{ name: 'English (United States)', value: 'en-US' },
{ name: 'English (Australia)', value: 'en-AU' },
{ name: 'English (United Kingdom)', value: 'en-GB' },
{ name: 'English (New Zealand)', value: 'en-NZ' },
{ name: 'English (India)', value: 'en-IN' },
{ name: 'Estonian', value: 'et' },
{ name: 'Finnish', value: 'fi' },
{ name: 'Flemish', value: 'nl-BE' },
{ name: 'French', value: 'fr' },
{ name: 'French (Canada)', value: 'fr-CA' },
{ name: 'German', value: 'de' },
{ name: 'German (Austria)', value: 'de-AT' },
{ name: 'German (Switzerland)', value: 'de-CH' },
{ name: 'Greek', value: 'el' },
{ name: 'German (Germany)', value: 'de-DE' },
{ name: 'Modern Greek', value: 'el' },
{ name: 'English', value: 'en' },
{ name: 'English (Australia)', value: 'en-AU' },
{ name: 'English (Canada)', value: 'en-CA' },
{ name: 'English (United Kingdom)', value: 'en-GB' },
{ name: 'English (Ireland)', value: 'en-IE' },
{ name: 'English (India)', value: 'en-IN' },
{ name: 'English (Malaysia)', value: 'en-MY' },
{ name: 'English (New Zealand)', value: 'en-NZ' },
{ name: 'English (Philippines)', value: 'en-PH' },
{ name: 'English (United States)', value: 'en-US' },
{ name: 'English (South Africa)', value: 'en-ZA' },
{ name: 'Spanish', value: 'es' },
{ name: 'Spanish (Latin America and the Caribbean)', value: 'es-419' },
{ name: 'Spanish (Argentina)', value: 'es-AR' },
{ name: 'Spanish (Colombia)', value: 'es-CO' },
{ name: 'Spanish (Spain)', value: 'es-ES' },
{ name: 'Spanish (Latin America)', value: 'es-LATAM' },
{ name: 'Spanish (Mexico)', value: 'es-MX' },
{ name: 'Spanish (United States)', value: 'es-US' },
{ name: 'Estonian', value: 'et' },
{ name: 'Basque', value: 'eu' },
{ name: 'Persian', value: 'fa' },
{ name: 'Finnish', value: 'fi' },
{ name: 'Faroese', value: 'fo' },
{ name: 'French', value: 'fr' },
{ name: 'French (Belgium)', value: 'fr-BE' },
{ name: 'French (Canada)', value: 'fr-CA' },
{ name: 'French (Switzerland)', value: 'fr-CH' },
{ name: 'French (France)', value: 'fr-FR' },
{ name: 'French (Canada)', value: 'fr-ca' },
{ name: 'Galician', value: 'gl' },
{ name: 'Gujarati', value: 'gu' },
{ name: 'Hausa', value: 'ha' },
{ name: 'Hawaiian', value: 'haw' },
{ name: 'Hebrew', value: 'he' },
{ name: 'Hindi', value: 'hi' },
{ name: 'Hindi (Latin)', value: 'hi-Latn' },
{ name: 'Croatian', value: 'hr' },
{ name: 'Haitian', value: 'ht' },
{ name: 'Hungarian', value: 'hu' },
{ name: 'Armenian', value: 'hy' },
{ name: 'Indonesian', value: 'id' },
{ name: 'Indonesian (Indonesia)', value: 'id-ID' },
{ name: 'Icelandic', value: 'is' },
{ name: 'Italian', value: 'it' },
{ name: 'Italian (Italy)', value: 'it-IT' },
{ name: 'Japanese', value: 'ja' },
{ name: 'Japanese (Japan)', value: 'ja-JP' },
{ name: 'Javanese', value: 'jw' },
{ name: 'Georgian', value: 'ka' },
{ name: 'Kazakh', value: 'kk' },
{ name: 'Khmer', value: 'km' },
{ name: 'Kannada', value: 'kn' },
{ name: 'Korean', value: 'ko' },
{ name: 'Korean (South Korea)', value: 'ko-KR' },
{ name: 'Latvian', value: 'lv' },
{ name: 'Korean (Republic of Korea)', value: 'ko-KR' },
{ name: 'Latin', value: 'la' },
{ name: 'Luxembourgish', value: 'lb' },
{ name: 'Lingala', value: 'ln' },
{ name: 'Lao', value: 'lo' },
{ name: 'Lithuanian', value: 'lt' },
{ name: 'Latvian', value: 'lv' },
{ name: 'Malagasy', value: 'mg' },
{ name: 'Maori', value: 'mi' },
{ name: 'Macedonian', value: 'mk' },
{ name: 'Malayalam', value: 'ml' },
{ name: 'Mongolian', value: 'mn' },
{ name: 'Marathi', value: 'mr' },
{ name: 'Malay', value: 'ms' },
{ name: 'Malay (Malaysia)', value: 'ms-MY' },
{ name: 'Malay (Singapore)', value: 'ms-SG' },
{ name: 'Maltese', value: 'mt' },
{ name: 'Burmese', value: 'my' },
{ name: 'Nepali', value: 'ne' },
{ name: 'Dutch', value: 'nl' },
{ name: 'Dutch (Belgium)', value: 'nl-BE' },
{ name: 'Dutch (Netherlands)', value: 'nl-NL' },
{ name: 'Norwegian Nynorsk', value: 'nn' },
{ name: 'Norwegian', value: 'no' },
{ name: 'Norwegian (Norway)', value: 'no-NO' },
{ name: 'Occitan', value: 'oc' },
{ name: 'Panjabi', value: 'pa' },
{ name: 'Polish', value: 'pl' },
{ name: 'Polish (Poland)', value: 'pl-PL' },
{ name: 'Pushto', value: 'ps' },
{ name: 'Portuguese', value: 'pt' },
{ name: 'Portuguese (Brazil)', value: 'pt-BR' },
{ name: 'Portuguese (Portugal)', value: 'pt-PT' },
{ name: 'Romanian', value: 'ro' },
{ name: 'Romanian (Moldova)', value: 'ro-MD' },
{ name: 'Russian', value: 'ru' },
{ name: 'Russian (Latin)', value: 'ru-Latn' },
{ name: 'Russian (Russian Federation)', value: 'ru-RU' },
{ name: 'Sanskrit', value: 'sa' },
{ name: 'Sindhi', value: 'sd' },
{ name: 'Sinhala', value: 'si' },
{ name: 'Slovak', value: 'sk' },
{ name: 'Spanish', value: 'es' },
{ name: 'Spanish (Latin America)', value: 'es-419' },
{ name: 'Slovenian', value: 'sl' },
{ name: 'Shona', value: 'sn' },
{ name: 'Somali', value: 'so' },
{ name: 'Albanian', value: 'sq' },
{ name: 'Serbian', value: 'sr' },
{ name: 'Sundanese', value: 'su' },
{ name: 'Swedish', value: 'sv' },
{ name: 'Swedish (Sweden)', value: 'sv-SE' },
{ name: 'Swahili', value: 'sw' },
{ name: 'Tamil', value: 'ta' },
{ name: 'Tamasheq', value: 'taq' },
{ name: 'Telugu', value: 'te' },
{ name: 'Tajik', value: 'tg' },
{ name: 'Thai', value: 'th' },
{ name: 'Thai (Thailand)', value: 'th-TH' },
{ name: 'Turkmen', value: 'tk' },
{ name: 'Tagalog', value: 'tl' },
{ name: 'Turkish', value: 'tr' },
{ name: 'Turkish (Türkiye)', value: 'tr-TR' },
{ name: 'Tatar', value: 'tt' },
{ name: 'Ukrainian', value: 'uk' },
{ name: 'Vietnamese', value: 'vi' }
{ name: 'Urdu', value: 'ur' },
{ name: 'Uzbek', value: 'uz' },
{ name: 'Vietnamese', value: 'vi' },
{ name: 'Yiddish', value: 'yi' },
{ name: 'Yoruba', value: 'yo' },
{ name: 'Chinese (Mandarin, Mainland)', value: 'zh' },
{ name: 'Chinese (China)', value: 'zh-CN' },
{ name: 'Chinese (Cantonese, Hong Kong)', value: 'zh-HK' },
{ name: 'Chinese (Han (Simplified variant))', value: 'zh-Hans' },
{ name: 'Chinese (Han (Traditional variant))', value: 'zh-Hant' },
{ name: 'Chinese (Traditional, Taiwan)', value: 'zh-TW' }
];

View File

@@ -0,0 +1,103 @@
module.exports = [
{ name: 'Afrikaans', value: 'af' },
{ name: 'Albanian', value: 'sq' },
{ name: 'Amharic', value: 'am' },
{ name: 'Arabic', value: 'ar' },
{ name: 'Armenian', value: 'hy' },
{ name: 'Assamese', value: 'as' },
{ name: 'Azerbaijani', value: 'az' },
{ name: 'Bashkir', value: 'ba' },
{ name: 'Basque', value: 'eu' },
{ name: 'Belarusian', value: 'be' },
{ name: 'Bengali', value: 'bn' },
{ name: 'Bosnian', value: 'bs' },
{ name: 'Breton', value: 'br' },
{ name: 'Bulgarian', value: 'bg' },
{ name: 'Cantonese', value: 'yue' },
{ name: 'Catalan', value: 'ca' },
{ name: 'Chinese', value: 'zh' },
{ name: 'Croatian', value: 'hr' },
{ name: 'Czech', value: 'cs' },
{ name: 'Danish', value: 'da' },
{ name: 'Dutch', value: 'nl' },
{ name: 'English', value: 'en' },
{ name: 'Estonian', value: 'et' },
{ name: 'Faroese', value: 'fo' },
{ name: 'Finnish', value: 'fi' },
{ name: 'French', value: 'fr' },
{ name: 'Galician', value: 'gl' },
{ name: 'Georgian', value: 'ka' },
{ name: 'German', value: 'de' },
{ name: 'Greek', value: 'el' },
{ name: 'Gujarati', value: 'gu' },
{ name: 'Haitian Creole', value: 'ht' },
{ name: 'Hausa', value: 'ha' },
{ name: 'Hawaiian', value: 'haw' },
{ name: 'Hebrew', value: 'he' },
{ name: 'Hindi', value: 'hi' },
{ name: 'Hungarian', value: 'hu' },
{ name: 'Icelandic', value: 'is' },
{ name: 'Indonesian', value: 'id' },
{ name: 'Italian', value: 'it' },
{ name: 'Japanese', value: 'ja' },
{ name: 'Javanese', value: 'jw' },
{ name: 'Kannada', value: 'kn' },
{ name: 'Kazakh', value: 'kk' },
{ name: 'Khmer', value: 'km' },
{ name: 'Korean', value: 'ko' },
{ name: 'Lao', value: 'lo' },
{ name: 'Latin', value: 'la' },
{ name: 'Latvian', value: 'lv' },
{ name: 'Lingala', value: 'ln' },
{ name: 'Lithuanian', value: 'lt' },
{ name: 'Luxembourgish', value: 'lb' },
{ name: 'Macedonian', value: 'mk' },
{ name: 'Malagasy', value: 'mg' },
{ name: 'Malay', value: 'ms' },
{ name: 'Malayalam', value: 'ml' },
{ name: 'Maltese', value: 'mt' },
{ name: 'Maori', value: 'mi' },
{ name: 'Marathi', value: 'mr' },
{ name: 'Mongolian', value: 'mn' },
{ name: 'Myanmar', value: 'my' },
{ name: 'Nepali', value: 'ne' },
{ name: 'Norwegian', value: 'no' },
{ name: 'Nynorsk', value: 'nn' },
{ name: 'Occitan', value: 'oc' },
{ name: 'Pashto', value: 'ps' },
{ name: 'Persian', value: 'fa' },
{ name: 'Polish', value: 'pl' },
{ name: 'Portuguese', value: 'pt' },
{ name: 'Punjabi', value: 'pa' },
{ name: 'Romanian', value: 'ro' },
{ name: 'Russian', value: 'ru' },
{ name: 'Sanskrit', value: 'sa' },
{ name: 'Serbian', value: 'sr' },
{ name: 'Shona', value: 'sn' },
{ name: 'Sindhi', value: 'sd' },
{ name: 'Sinhala', value: 'si' },
{ name: 'Slovak', value: 'sk' },
{ name: 'Slovenian', value: 'sl' },
{ name: 'Somali', value: 'so' },
{ name: 'Spanish', value: 'es' },
{ name: 'Sundanese', value: 'su' },
{ name: 'Swahili', value: 'sw' },
{ name: 'Swedish', value: 'sv' },
{ name: 'Tagalog', value: 'tl' },
{ name: 'Tajik', value: 'tg' },
{ name: 'Tamil', value: 'ta' },
{ name: 'Tatar', value: 'tt' },
{ name: 'Telugu', value: 'te' },
{ name: 'Thai', value: 'th' },
{ name: 'Tibetan', value: 'bo' },
{ name: 'Turkish', value: 'tr' },
{ name: 'Turkmen', value: 'tk' },
{ name: 'Ukrainian', value: 'uk' },
{ name: 'Urdu', value: 'ur' },
{ name: 'Uzbek', value: 'uz' },
{ name: 'Vietnamese', value: 'vi' },
{ name: 'Welsh', value: 'cy' },
{ name: 'Wolof', value: 'wo' },
{ name: 'Yiddish', value: 'yi' },
{ name: 'Yoruba', value: 'yo' }
];

View File

@@ -0,0 +1,19 @@
module.exports = [
{ name: 'English', value: 'en' },
{ name: 'Spanish', value: 'es' },
{ name: 'Portuguese', value: 'pt' },
{ name: 'French', value: 'fr' },
{ name: 'Indian-accented English', value: 'en-IN' },
{ name: 'German', value: 'de' },
{ name: 'Dutch', value: 'nl' },
{ name: 'Italian', value: 'it' },
{ name: 'Korean', value: 'ko' },
{ name: 'Japanese', value: 'ja' },
{ name: 'Mandarin', value: 'zh-CN' },
{ name: 'Russian', value: 'ru' },
{ name: 'Polish', value: 'pl' },
{ name: 'Swedish', value: 'sv' },
{ name: 'Arabic', value: 'ar' },
{ name: 'Turkish', value: 'tr' },
{ name: 'Hebrew', value: 'he' },
];

View File

@@ -5,6 +5,8 @@ const sdk = require('microsoft-cognitiveservices-speech-sdk');
const { SpeechClient } = require('@soniox/soniox-node');
const fs = require('fs');
const { AssemblyAI } = require('assemblyai');
const Houndify = require('houndify');
const { GladiaClient } = require('@gladiaio/sdk');
const {decrypt, obscureKey} = require('./encrypt-decrypt');
const { RealtimeSession } = require('speechmatics');
@@ -45,9 +47,11 @@ const SttCobaltLanguagesVoices = require('./speech-data/stt-cobalt');
const SttSonioxLanguagesVoices = require('./speech-data/stt-soniox');
const SttSpeechmaticsLanguagesVoices = require('./speech-data/stt-speechmatics');
const SttAssemblyaiLanguagesVoices = require('./speech-data/stt-assemblyai');
const SttHoundifyLanguagesVoices = require('./speech-data/stt-houndify');
const SttVoxistLanguagesVoices = require('./speech-data/stt-voxist');
const SttVerbioLanguagesVoices = require('./speech-data/stt-verbio');
const SttOpenaiLanguagesVoices = require('./speech-data/stt-openai');
const SttGladiaLanguagesVoices = require('./speech-data/stt-gladia');
const SttModelOpenai = require('./speech-data/stt-model-openai');
@@ -168,6 +172,65 @@ const testGoogleStt = async(logger, credentials) => {
}
};
const testGladiaStt = async(logger, credentials) => {
const {api_key} = credentials;
try {
const gladiaClient = new GladiaClient({
apiKey: api_key,
});
const gladiaConfig = {
model: 'solaria-1',
encoding: 'wav/pcm',
sample_rate: 16000,
bit_depth: 16,
channels: 1,
language_config: {
languages: ['en'],
code_switching: false,
},
};
// Start the live session
const liveSession = gladiaClient.liveV2().startSession(gladiaConfig);
// Read the test audio file
const audioBuffer = fs.readFileSync(`${__dirname}/../../data/test_audio.wav`);
// Wait for final transcript
return new Promise((resolve, reject) => {
liveSession.on('message', (message) => {
if (message.type === 'transcript' && message.data.is_final) {
logger.debug(`${message.data.id}: ${message.data.utterance.text}`);
liveSession.stopRecording();
resolve(message.data.utterance.text);
}
});
liveSession.on('error', (error) => {
logger.error({error}, 'Gladia Live STT error');
reject(error);
});
// Send audio in chunks
const chunkSize = 1024;
for (let i = 0; i < audioBuffer.length; i += chunkSize) {
const chunk = audioBuffer.slice(i, i + chunkSize);
liveSession.sendAudio(chunk);
}
// Stop recording after sending all audio
liveSession.stopRecording();
// Set a timeout to prevent hanging
setTimeout(() => {
reject(new Error('Gladia STT test timeout'));
}, 30000); // 30 second timeout
});
} catch (error) {
logger.error({error}, 'Failed to create Gladia Live STT session');
throw error;
}
};
const testDeepgramStt = async(logger, credentials) => {
const {api_key, deepgram_stt_uri, deepgram_stt_use_tls} = credentials;
const deepgram = new Deepgram(api_key, deepgram_stt_uri, deepgram_stt_uri && deepgram_stt_use_tls);
@@ -316,8 +379,8 @@ const testWellSaidTts = async(logger, credentials) => {
};
const testElevenlabs = async(logger, credentials) => {
const {api_key, model_id} = credentials;
const response = await fetch('https://api.elevenlabs.io/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM', {
const {api_key, model_id, api_uri} = credentials;
const response = await fetch(`https://${api_uri || 'api.elevenlabs.io'}/v1/text-to-speech/21m00Tcm4TlvDq8ikWAM`, {
method: 'POST',
headers: {
'xi-api-key': api_key,
@@ -595,6 +658,72 @@ const testAssemblyStt = async(logger, credentials) => {
});
};
const testHoundifyStt = async(logger, credentials) => {
const {client_id, client_key, user_id} = credentials;
return new Promise((resolve, reject) => {
try {
// Read the test audio file
const audioBuffer = fs.readFileSync(`${__dirname}/../../data/test_audio.wav`);
// Create VoiceRequest for speech-to-text testing
const voiceRequest = new Houndify.VoiceRequest({
// Your Houndify Client ID and Key
clientId: client_id,
clientKey: client_key,
// Request info
requestInfo: {
UserID: user_id || 'test_user',
Latitude: 37.388309,
Longitude: -121.973968
},
// Audio format configuration
sampleRate: 16000,
enableVAD: true,
// Response and error handlers
onResponse: function(response, info) {
logger.debug({response, info}, 'Houndify STT response received');
if (response && response.AllResults && response.AllResults.length > 0) {
resolve(response);
} else {
reject(new Error('No transcription results received'));
}
},
onError: function(err, info) {
logger.error({err, info}, 'Houndify STT error');
reject(err);
},
onRecordingStarted: function() {
logger.debug('Houndify recording started');
},
onRecordingStopped: function() {
logger.debug('Houndify recording stopped');
}
});
// Send audio in chunks (VoiceRequest automatically starts when you write data)
const chunkSize = 1024;
for (let i = 0; i < audioBuffer.length; i += chunkSize) {
const chunk = audioBuffer.slice(i, i + chunkSize);
voiceRequest.write(chunk);
}
// End the request
voiceRequest.end();
} catch (error) {
logger.error({error}, 'Failed to create Houndify VoiceRequest');
reject(error);
}
});
};
const testVoxistStt = async(logger, credentials) => {
const {api_key} = credentials;
const response = await fetch('https://api-asr.voxist.com/clients', {
@@ -686,7 +815,11 @@ function decryptCredential(obj, credential, logger, isObscureKey = true) {
obj.deepgram_tts_uri = o.deepgram_tts_uri;
obj.model_id = o.model_id;
}
else if ('deepgramriver' === obj.vendor) {
else if ('deepgramflux' === obj.vendor) {
const o = JSON.parse(decrypt(credential));
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
}
else if ('gladia' === obj.vendor) {
const o = JSON.parse(decrypt(credential));
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
}
@@ -714,6 +847,7 @@ function decryptCredential(obj, credential, logger, isObscureKey = true) {
const o = JSON.parse(decrypt(credential));
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
obj.model_id = o.model_id;
obj.api_uri = o.api_uri;
obj.options = o.options;
} else if ('playht' === obj.vendor) {
const o = JSON.parse(decrypt(credential));
@@ -748,7 +882,12 @@ function decryptCredential(obj, credential, logger, isObscureKey = true) {
const o = JSON.parse(decrypt(credential));
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
obj.service_version = o.service_version;
} else if ('resemble' === obj.vendor) {
} else if ('houndify' === obj.vendor) {
const o = JSON.parse(decrypt(credential));
obj.client_key = isObscureKey ? obscureKey(o.client_key) : o.client_key;
obj.client_id = o.client_id;
obj.user_id = o.user_id;
} else if ('resemble' === obj.vendor) {
const o = JSON.parse(decrypt(credential));
obj.api_key = isObscureKey ? obscureKey(o.api_key) : o.api_key;
obj.resemble_tts_uri = o.resemble_tts_uri;
@@ -807,6 +946,8 @@ async function getLanguagesAndVoicesForVendor(logger, vendor, credential, getTts
return await getLanguagesVoicesForNuane(credential, getTtsVoices, logger);
case 'deepgram':
return await getLanguagesVoicesForDeepgram(credential, getTtsVoices, logger);
case 'gladia':
return await getLanguagesVoicesForGladia(credential, getTtsVoices, logger);
case 'ibm':
return await getLanguagesVoicesForIbm(credential, getTtsVoices, logger);
case 'nvidia':
@@ -827,6 +968,8 @@ async function getLanguagesAndVoicesForVendor(logger, vendor, credential, getTts
return await getLanguagesAndVoicesForResemble(credential, getTtsVoices, logger);
case 'assemblyai':
return await getLanguagesVoicesForAssemblyAI(credential, getTtsVoices, logger);
case 'houndify':
return await getLanguagesVoicesForHoundify(credential, getTtsVoices, logger);
case 'voxist':
return await getLanguagesVoicesForVoxist(credential, getTtsVoices, logger);
case 'whisper':
@@ -935,8 +1078,30 @@ async function getLanguagesVoicesForDeepgram(credential, getTtsVoices, logger) {
logger.error({response}, 'Error fetching Deepgram voices');
throw new Error('failed to list voices');
}
const {stt, tts} = await response.json();
let sttLangs = SttDeepgramLanguagesVoices;
const {stt, tts, languages} = await response.json();
// Helper function to get language name
const getLanguageName = (langCode) => {
if (languages && languages[langCode]) {
return languages[langCode];
}
const existingLang = SttDeepgramLanguagesVoices.find((l) => l.value === langCode);
return existingLang ? existingLang.name : capitalizeFirst(langCode);
};
// Collect unique languages from selected models
const allSttLanguages = new Set();
const modelsToProcess = model_id ?
stt.filter((m) => m.canonical_name === model_id) :
stt;
modelsToProcess.forEach((model) => {
if (model.languages && Array.isArray(model.languages)) {
model.languages.forEach((lang) => allSttLanguages.add(lang));
}
});
// Convert to expected format
const sttLangs = Array.from(allSttLanguages).map((langCode) => ({
name: getLanguageName(langCode),
value: langCode
})).sort((a, b) => a.name.localeCompare(b.name));
const sttModels = Array.from(
new Map(
stt.map((m) => [m.canonical_name, { name: capitalizeFirst(m.canonical_name), value: m.canonical_name }])
@@ -947,16 +1112,6 @@ async function getLanguagesVoicesForDeepgram(credential, getTtsVoices, logger) {
tts.map((m) => [m.canonical_name, { name: capitalizeFirst(m.canonical_name), value: m.canonical_name }])
).values()
).sort((a, b) => a.name.localeCompare(b.name));
// if model_id is not provided, return all models, all voices, all languages
if (!model_id) {
return tranform(TtsLanguagesDeepgram, sttLangs, ttsModels, sttModels);
}
const selectedSttModel = stt.find((m) => m.canonical_name === model_id);
const selectedSttLangs = selectedSttModel ? selectedSttModel.languages : [];
sttLangs = SttDeepgramLanguagesVoices.filter((l) => {
return selectedSttLangs.includes(l.value);
});
return tranform(TtsLanguagesDeepgram, sttLangs, ttsModels, sttModels);
}
}
@@ -964,6 +1119,11 @@ async function getLanguagesVoicesForDeepgram(credential, getTtsVoices, logger) {
TtsModelDeepgram, sttModelDeepgram.sort((a, b) => a.name.localeCompare(b.name)));
}
async function getLanguagesVoicesForGladia(credential, getTtsVoices, logger) {
return tranform(undefined, SttGladiaLanguagesVoices.sort((a, b) => a.name.localeCompare(b.name)),
undefined, undefined);
}
async function getLanguagesVoicesForIbm(credential, getTtsVoices, logger) {
if (credential) {
try {
@@ -1002,10 +1162,12 @@ async function getLanguagesVoicesForElevenlabs(credential) {
'xi-api-key': credential.api_key
};
const getModelPromise = fetch('https://api.elevenlabs.io/v1/models', {
const api_uri = credential.api_uri || 'api.elevenlabs.io';
const getModelPromise = fetch(`https://${api_uri}/v1/models`, {
headers
});
const getVoicePromise = fetch('https://api.elevenlabs.io/v1/voices', {
const getVoicePromise = fetch(`https://${api_uri}/v1/voices`, {
headers
});
const [langResp, voiceResp] = await Promise.all([getModelPromise, getVoicePromise]);
@@ -1234,6 +1396,10 @@ async function getLanguagesVoicesForAssemblyAI(credential) {
return tranform(undefined, SttAssemblyaiLanguagesVoices);
}
async function getLanguagesVoicesForHoundify(credential) {
return tranform(undefined, SttHoundifyLanguagesVoices);
}
async function getLanguagesVoicesForVoxist(credential) {
return tranform(undefined, SttVoxistLanguagesVoices);
}
@@ -1612,6 +1778,7 @@ module.exports = {
testNuanceTts,
testNuanceStt,
testDeepgramStt,
testGladiaStt,
testIbmTts,
testIbmStt,
testSonioxStt,
@@ -1631,5 +1798,6 @@ module.exports = {
testCartesia,
testVoxistStt,
testOpenAiStt,
testResembleTTS
testResembleTTS,
testHoundifyStt
};

656
package-lock.json generated
View File

@@ -14,15 +14,16 @@
"@aws-sdk/client-transcribe": "^3.549.0",
"@azure/storage-blob": "^12.17.0",
"@deepgram/sdk": "^1.21.0",
"@gladiaio/sdk": "^0.5.2",
"@google-cloud/speech": "^6.5.0",
"@google-cloud/storage": "^7.9.0",
"@jambonz/db-helpers": "^0.9.12",
"@jambonz/db-helpers": "^0.9.18",
"@jambonz/lamejs": "^1.2.2",
"@jambonz/mw-registrar": "^0.2.7",
"@jambonz/realtimedb-helpers": "^0.8.15",
"@jambonz/speech-utils": "^0.2.17",
"@jambonz/speech-utils": "^0.2.25",
"@jambonz/time-series": "^0.2.8",
"@jambonz/verb-specifications": "^0.0.111",
"@jambonz/verb-specifications": "^0.0.118",
"@soniox/soniox-node": "^1.2.2",
"ajv": "^8.17.1",
"argon2": "^0.40.1",
@@ -33,6 +34,7 @@
"express-rate-limit": "^7.2.0",
"form-data": "^4.0.0",
"helmet": "^7.1.0",
"houndify": "^3.1.14",
"ibm-watson": "^9.0.1",
"is-valid-hostname": "^1.0.2",
"jsonwebtoken": "^9.0.2",
@@ -3219,14 +3221,12 @@
}
},
"node_modules/@babel/code-frame": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"license": "MIT",
"version": "7.24.2",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
"integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
"js-tokens": "^4.0.0",
"picocolors": "^1.1.1"
"@babel/highlight": "^7.24.2",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
@@ -3431,20 +3431,18 @@
}
},
"node_modules/@babel/helper-string-parser": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
"integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/helper-validator-identifier": {
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"license": "MIT",
"version": "7.22.20",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
"engines": {
"node": ">=6.9.0"
}
@@ -3459,28 +3457,102 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.27.6",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz",
"integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==",
"version": "7.24.4",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz",
"integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.27.2",
"@babel/types": "^7.27.6"
"@babel/template": "^7.24.0",
"@babel/traverse": "^7.24.1",
"@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz",
"integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==",
"dev": true,
"license": "MIT",
"node_modules/@babel/highlight": {
"version": "7.24.2",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.2.tgz",
"integrity": "sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==",
"dependencies": {
"@babel/types": "^7.28.0"
"@babel/helper-validator-identifier": "^7.22.20",
"chalk": "^2.4.2",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/highlight/node_modules/ansi-styles": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
"dependencies": {
"color-convert": "^1.9.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/chalk": {
"version": "2.4.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dependencies": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dependencies": {
"color-name": "1.1.3"
}
},
"node_modules/@babel/highlight/node_modules/color-name": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
},
"node_modules/@babel/highlight/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
"engines": {
"node": ">=0.8.0"
}
},
"node_modules/@babel/highlight/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/highlight/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/@babel/parser": {
"version": "7.24.4",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
"integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -3489,15 +3561,14 @@
}
},
"node_modules/@babel/template": {
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"version": "7.24.0",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
"integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/parser": "^7.27.2",
"@babel/types": "^7.27.1"
"@babel/code-frame": "^7.23.5",
"@babel/parser": "^7.24.0",
"@babel/types": "^7.24.0"
},
"engines": {
"node": ">=6.9.0"
@@ -3534,14 +3605,14 @@
}
},
"node_modules/@babel/types": {
"version": "7.28.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.1.tgz",
"integrity": "sha512-x0LvFTekgSX+83TI28Y9wYPUfzrnl2aT5+5QLnO6v7mSJYtEEevuDRN0F0uSHRk1G1IWZC43o00Y0xDDrpBGPQ==",
"version": "7.24.0",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
"integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
"@babel/helper-validator-identifier": "^7.27.1"
"@babel/helper-string-parser": "^7.23.4",
"@babel/helper-validator-identifier": "^7.22.20",
"to-fast-properties": "^2.0.0"
},
"engines": {
"node": ">=6.9.0"
@@ -3723,6 +3794,28 @@
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@gladiaio/sdk": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@gladiaio/sdk/-/sdk-0.5.2.tgz",
"integrity": "sha512-v51y75+5Wg/YWVQlTXGdOFiKTrYAHdWR3xZoCqLQdWPyBlynVbiTPf4IpID0zAP/ngu16GGmBVC/XOQZfcj+hg==",
"license": "MIT",
"engines": {
"node": ">=20"
},
"peerDependencies": {
"eventemitter3": ">=5",
"undici": ">=5",
"ws": "5.2.4 || 6.2.3 || 7.5.10 || >=8.8"
},
"peerDependenciesMeta": {
"undici": {
"optional": true
},
"ws": {
"optional": true
}
}
},
"node_modules/@google-cloud/common": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.1.tgz",
@@ -4039,13 +4132,12 @@
}
},
"node_modules/@jambonz/db-helpers": {
"version": "0.9.12",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.12.tgz",
"integrity": "sha512-cmUuh6G2yqsPZxx0v0iKq0puCaWPz6RGaHvMxBZlolEfLHxTcHshgm+Y/L7J3/4bEKaovzP4z7TXh/pab7mZig==",
"version": "0.9.18",
"resolved": "https://registry.npmjs.org/@jambonz/db-helpers/-/db-helpers-0.9.18.tgz",
"integrity": "sha512-rrrBzz6UnEW0LV4OXRUzjg2XzwUGNjuJptKPxozvCQYOSuXQsRYcc7AM+p32ssBd+LdTX866pQ0QwRc2cUEAPw==",
"license": "MIT",
"dependencies": {
"cidr-matcher": "^2.1.1",
"debug": "^4.3.4",
"mysql2": "^3.11.0",
"node-object-hash": "^2.3.10",
"uuid": "^8.3.2"
@@ -4086,9 +4178,9 @@
}
},
"node_modules/@jambonz/speech-utils": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/@jambonz/speech-utils/-/speech-utils-0.2.17.tgz",
"integrity": "sha512-YcBq8bOvo5QfQJQXP4e2N0sCPqkoW0jNM4eHhspJotJc7V9DB3T5VVA6SGUsDXDZUwyT0JPI3Tx+xof02eWQ2Q==",
"version": "0.2.25",
"resolved": "https://registry.npmjs.org/@jambonz/speech-utils/-/speech-utils-0.2.25.tgz",
"integrity": "sha512-dtMY4SoGhpvKM6slPvTlMz61Fd0Rxnajwm3sJVxlAYZnFtzfIvqg9rrYUN4h05tJbo/4TLs15/dVeicw7dTnew==",
"license": "MIT",
"dependencies": {
"23": "^0.0.0",
@@ -4153,15 +4245,15 @@
}
},
"node_modules/@jambonz/speech-utils/node_modules/ibm-cloud-sdk-core": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-5.4.2.tgz",
"integrity": "sha512-5VFkKYU/vSIWFJTVt392XEdPmiEwUJqhxjn1MRO3lfELyU2FB+yYi8brbmXUgq+D1acHR1fpS7tIJ6IlnrR9Cg==",
"version": "5.4.3",
"resolved": "https://registry.npmjs.org/ibm-cloud-sdk-core/-/ibm-cloud-sdk-core-5.4.3.tgz",
"integrity": "sha512-D0lvClcoCp/HXyaFlCbOT4aTYgGyeIb4ncxZpxRuiuw7Eo79C6c49W53+8WJRD9nxzT5vrIdaky3NBcTdBtaEg==",
"license": "Apache-2.0",
"dependencies": {
"@types/debug": "^4.1.12",
"@types/node": "^18.19.80",
"@types/tough-cookie": "^4.0.0",
"axios": "^1.11.0",
"axios": "^1.12.2",
"camelcase": "^6.3.0",
"debug": "^4.3.4",
"dotenv": "^16.4.5",
@@ -4179,9 +4271,9 @@
}
},
"node_modules/@jambonz/speech-utils/node_modules/ibm-cloud-sdk-core/node_modules/@types/node": {
"version": "18.19.122",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.122.tgz",
"integrity": "sha512-yzegtT82dwTNEe/9y+CM8cgb42WrUfMMCg2QqSddzO1J6uPmBD7qKCZ7dOHZP2Yrpm/kb0eqdNMn2MUyEiqBmA==",
"version": "18.19.130",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
"integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
"license": "MIT",
"dependencies": {
"undici-types": "~5.26.4"
@@ -4254,9 +4346,9 @@
}
},
"node_modules/@jambonz/verb-specifications": {
"version": "0.0.111",
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.111.tgz",
"integrity": "sha512-P2lDki5wCHGPPXpPTeMdht4NfGujF6NrLyrI8o/4U6l+2elfc/1mKl/Lz/PWGo9rQM4mTOVIhkk9ECo0NvOVoA==",
"version": "0.0.118",
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.118.tgz",
"integrity": "sha512-1dGnc6TUCehjt1yGNuqh1uzk1xw9HhUm39aVUosQMHlnT0fK0ItikeJ0uttTjFastHNmPPxqJwb20wOvVGTCFg==",
"license": "MIT",
"dependencies": {
"debug": "^4.3.4",
@@ -5837,7 +5929,6 @@
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
"integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==",
"dev": true,
"dependencies": {
"possible-typed-array-names": "^1.0.0"
},
@@ -5858,9 +5949,9 @@
}
},
"node_modules/axios": {
"version": "1.11.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz",
"integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==",
"version": "1.12.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
"integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
@@ -5973,10 +6064,9 @@
"integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA=="
},
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -6129,15 +6219,15 @@
}
},
"node_modules/call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
"integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
"set-function-length": "^1.2.2"
},
"engines": {
"node": ">= 0.4"
@@ -6159,6 +6249,22 @@
"node": ">= 0.4"
}
},
"node_modules/call-bound": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
"integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/callsites": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@@ -6227,6 +6333,20 @@
"ip6addr": "^0.2.2"
}
},
"node_modules/cipher-base": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz",
"integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"safe-buffer": "^5.2.1",
"to-buffer": "^1.2.2"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/clean-stack": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
@@ -6413,6 +6533,42 @@
"node": ">= 0.10"
}
},
"node_modules/create-hash": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"md5.js": "^1.3.4",
"ripemd160": "^2.0.1",
"sha.js": "^2.4.0"
}
},
"node_modules/create-hmac": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"license": "MIT",
"dependencies": {
"cipher-base": "^1.0.3",
"create-hash": "^1.1.0",
"inherits": "^2.0.1",
"ripemd160": "^2.0.0",
"safe-buffer": "^5.0.1",
"sha.js": "^2.4.8"
}
},
"node_modules/cross-fetch": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
"integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
"license": "MIT",
"dependencies": {
"node-fetch": "^2.7.0"
}
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
@@ -6941,6 +7097,21 @@
"es6-symbol": "^3.1.1"
}
},
"node_modules/es6-promise": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
"license": "MIT"
},
"node_modules/es6-promisify": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==",
"license": "MIT",
"dependencies": {
"es6-promise": "^4.0.3"
}
},
"node_modules/es6-symbol": {
"version": "3.1.4",
"resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
@@ -7208,6 +7379,13 @@
"node": ">=6"
}
},
"node_modules/eventemitter3": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==",
"license": "MIT",
"peer": true
},
"node_modules/events": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -7290,6 +7468,42 @@
"express": "4 || 5 || ^5.0.0-beta.1"
}
},
"node_modules/express-ws": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/express-ws/-/express-ws-5.0.2.tgz",
"integrity": "sha512-0uvmuk61O9HXgLhGl3QhNSEtRsQevtmbL94/eILaliEADZBHZOQUAiHFrGPrgsjikohyrmSG5g+sCfASTt0lkQ==",
"license": "BSD-2-Clause",
"dependencies": {
"ws": "^7.4.6"
},
"engines": {
"node": ">=4.5.0"
},
"peerDependencies": {
"express": "^4.0.0 || ^5.0.0-alpha.1"
}
},
"node_modules/express-ws/node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"license": "MIT",
"engines": {
"node": ">=8.3.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/express/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -7538,12 +7752,18 @@
}
},
"node_modules/for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
"integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
"license": "MIT",
"dependencies": {
"is-callable": "^1.1.3"
"is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/foreground-child": {
@@ -8008,6 +8228,63 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hash-base": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz",
"integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==",
"license": "MIT",
"dependencies": {
"inherits": "^2.0.4",
"readable-stream": "^2.3.8",
"safe-buffer": "^5.2.1",
"to-buffer": "^1.2.1"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/hash-base/node_modules/isarray": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
"license": "MIT"
},
"node_modules/hash-base/node_modules/readable-stream": {
"version": "2.3.8",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
"integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
"license": "MIT",
"dependencies": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/hash-base/node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"license": "MIT",
"dependencies": {
"safe-buffer": "~5.1.0"
}
},
"node_modules/hash-base/node_modules/string_decoder/node_modules/safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
"license": "MIT"
},
"node_modules/hasha": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz",
@@ -8052,6 +8329,99 @@
"node": ">=16.0.0"
}
},
"node_modules/houndify": {
"version": "3.1.14",
"resolved": "https://registry.npmjs.org/houndify/-/houndify-3.1.14.tgz",
"integrity": "sha512-CLeEdihgeeTtKmcnlAXK/wDKbWDDUeZpbTQLAG2Guu2AbPxyH1f+HO04jiqA/RUlwAQxPZr3YRX/LaMbkEeb6w==",
"license": "MIT",
"dependencies": {
"axios": "^0.21.4",
"create-hmac": "^1.1.6",
"cross-fetch": "^3.1.5",
"express": "^4.17.0",
"express-ws": "^5.0.2",
"https-proxy-agent": "^2.2.4",
"json-bigint": "^1.0.0",
"pako": "^1.0.5",
"uuid": "^3.1.0",
"wav": "^1.0.2",
"ws": "^7.5.7"
}
},
"node_modules/houndify/node_modules/agent-base": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
"license": "MIT",
"dependencies": {
"es6-promisify": "^5.0.0"
},
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/houndify/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/houndify/node_modules/debug": {
"version": "3.2.7",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
"integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.1"
}
},
"node_modules/houndify/node_modules/https-proxy-agent": {
"version": "2.2.4",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz",
"integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==",
"license": "MIT",
"dependencies": {
"agent-base": "^4.3.0",
"debug": "^3.1.0"
},
"engines": {
"node": ">= 4.5.0"
}
},
"node_modules/houndify/node_modules/uuid": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
"deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
"license": "MIT",
"bin": {
"uuid": "bin/uuid"
}
},
"node_modules/houndify/node_modules/ws": {
"version": "7.5.10",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
"integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
"license": "MIT",
"engines": {
"node": ">=8.3.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
@@ -8409,7 +8779,6 @@
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
"integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
@@ -8634,12 +9003,12 @@
}
},
"node_modules/is-typed-array": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
"integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
"dev": true,
"version": "1.1.15",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
"integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"license": "MIT",
"dependencies": {
"which-typed-array": "^1.1.14"
"which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
@@ -8711,8 +9080,7 @@
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
},
"node_modules/isexe": {
"version": "2.0.0",
@@ -8910,8 +9278,7 @@
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
},
"node_modules/js-yaml": {
"version": "4.1.0",
@@ -9214,6 +9581,17 @@
"node": ">= 0.4"
}
},
"node_modules/md5.js": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
"integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==",
"license": "MIT",
"dependencies": {
"hash-base": "^3.0.0",
"inherits": "^2.0.1",
"safe-buffer": "^5.1.2"
}
},
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -9967,6 +10345,12 @@
"node": ">=8"
}
},
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
"license": "(MIT AND Zlib)"
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -10079,10 +10463,9 @@
}
},
"node_modules/picocolors": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC"
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
},
"node_modules/picomatch": {
"version": "2.3.1",
@@ -10213,7 +10596,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
"integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
@@ -10632,6 +11014,19 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ripemd160": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz",
"integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==",
"license": "MIT",
"dependencies": {
"hash-base": "^3.1.2",
"inherits": "^2.0.4"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -10862,6 +11257,26 @@
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/sha.js": {
"version": "2.4.12",
"resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz",
"integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==",
"license": "(MIT AND BSD-3-Clause)",
"dependencies": {
"inherits": "^2.0.4",
"safe-buffer": "^5.2.1",
"to-buffer": "^1.2.0"
},
"bin": {
"sha.js": "bin.js"
},
"engines": {
"node": ">= 0.10"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
@@ -11385,6 +11800,29 @@
"real-require": "^0.2.0"
}
},
"node_modules/to-buffer": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz",
"integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==",
"license": "MIT",
"dependencies": {
"isarray": "^2.0.5",
"safe-buffer": "^5.2.1",
"typed-array-buffer": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
"dev": true,
"engines": {
"node": ">=4"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -11494,14 +11932,14 @@
}
},
"node_modules/typed-array-buffer": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
"integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
"dev": true,
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
"integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"call-bound": "^1.0.3",
"es-errors": "^1.3.0",
"is-typed-array": "^1.1.13"
"is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@@ -11896,15 +12334,17 @@
"dev": true
},
"node_modules/which-typed-array": {
"version": "1.1.15",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
"integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
"dev": true,
"version": "1.1.19",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
"integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"call-bind": "^1.0.8",
"call-bound": "^1.0.4",
"for-each": "^0.3.5",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-tostringtag": "^1.0.2"
},
"engines": {

View File

@@ -25,15 +25,16 @@
"@aws-sdk/client-transcribe": "^3.549.0",
"@azure/storage-blob": "^12.17.0",
"@deepgram/sdk": "^1.21.0",
"@gladiaio/sdk": "^0.5.2",
"@google-cloud/speech": "^6.5.0",
"@google-cloud/storage": "^7.9.0",
"@jambonz/db-helpers": "^0.9.12",
"@jambonz/db-helpers": "^0.9.18",
"@jambonz/lamejs": "^1.2.2",
"@jambonz/mw-registrar": "^0.2.7",
"@jambonz/realtimedb-helpers": "^0.8.15",
"@jambonz/speech-utils": "^0.2.17",
"@jambonz/speech-utils": "^0.2.25",
"@jambonz/time-series": "^0.2.8",
"@jambonz/verb-specifications": "^0.0.111",
"@jambonz/verb-specifications": "^0.0.118",
"@soniox/soniox-node": "^1.2.2",
"ajv": "^8.17.1",
"argon2": "^0.40.1",
@@ -44,6 +45,7 @@
"express-rate-limit": "^7.2.0",
"form-data": "^4.0.0",
"helmet": "^7.1.0",
"houndify": "^3.1.14",
"ibm-watson": "^9.0.1",
"is-valid-hostname": "^1.0.2",
"jsonwebtoken": "^9.0.2",

View File

@@ -656,7 +656,8 @@ test('speech credentials tests', async(t) => {
use_for_stt: true,
use_for_tts: false,
api_key: 'asdasdasdasddsadasda',
model_id: 'eleven_multilingual_v2'
model_id: 'eleven_multilingual_v2',
api_uri: 'api.elevenlabs.io'
}
});
t.ok(result.statusCode === 201, 'successfully added speech credential for elevenlabs');
@@ -805,6 +806,29 @@ test('speech credentials tests', async(t) => {
});
t.ok(result.statusCode === 204, 'successfully deleted speech credential');
/* add a credential for houndify */
result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
vendor: 'houndify',
use_for_stt: true,
client_key: "ClientKey",
client_id: "ClientID",
user_id: "test_user"
}
});
t.ok(result.statusCode === 201, 'successfully added speech credential for houndify');
const houndifySid = result.body.sid;
/* delete the credential */
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${houndifySid}`, {
auth: authUser,
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 204, 'successfully deleted speech credential');
/* add a credential for Voxist */
result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, {
resolveWithFullResponse: true,
@@ -930,21 +954,43 @@ test('speech credentials tests', async(t) => {
auth: authUser,
json: true,
body: {
vendor: 'deepgramriver',
vendor: 'deepgramflux',
use_for_tts: false,
use_for_stt: true,
api_key: 'api_key',
}
});
t.ok(result.statusCode === 201, 'successfully added speech credential for Verbio');
const deepgramriverSid = result.body.sid;
const deepgramfluxSid = result.body.sid;
/* delete the credential */
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${deepgramriverSid}`, {
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${deepgramfluxSid}`, {
auth: authUser,
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 204, 'successfully deleted speech credential deepgramriver');
t.ok(result.statusCode === 204, 'successfully deleted speech credential deepgramflux');
/* add a credential for gladia */
result = await request.post(`/Accounts/${account_sid}/SpeechCredentials`, {
resolveWithFullResponse: true,
auth: authUser,
json: true,
body: {
vendor: 'gladia',
use_for_tts: false,
use_for_stt: true,
api_key: 'api_key',
}
});
t.ok(result.statusCode === 201, 'successfully added speech credential for Gladia');
const gladiaSid = result.body.sid;
/* delete the credential */
result = await request.delete(`/Accounts/${account_sid}/SpeechCredentials/${gladiaSid}`, {
auth: authUser,
resolveWithFullResponse: true,
});
t.ok(result.statusCode === 204, 'successfully deleted speech credential for Gladia');
/* Check google supportedLanguagesAndVoices */
result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/speech/supportedLanguagesAndVoices?vendor=google`, {
@@ -1081,6 +1127,15 @@ test('speech credentials tests', async(t) => {
t.ok(result.body.tts.length !== 0, 'successfully get whisper supported languages and voices');
t.ok(result.body.models.length !== 0, 'successfully get whisper supported languages and voices');
/* Check gladia supportedLanguagesAndVoices */
result = await request.get(`/Accounts/${account_sid}/SpeechCredentials/speech/supportedLanguagesAndVoices?vendor=gladia`, {
resolveWithFullResponse: true,
simple: false,
auth: authAdmin,
json: true,
});
t.ok(result.body.stt.length !== 0, 'successfully get gladia supported languages and voices');
await deleteObjectBySid(request, '/Accounts', account_sid);
await deleteObjectBySid(request, '/ServiceProviders', service_provider_sid);
t.end();