fix to be more precise about removing custom event handlers so that w… (#580)

* fix to be more precise about removing custom event handlers so that when we stop a gather we dont also inadvertently stop a background transcribe as well

* test fixes

* fix: endpointing=false was being ignored for Deepgram
This commit is contained in:
Dave Horton
2023-12-28 11:00:27 -05:00
committed by GitHub
parent 9d8291f892
commit 2c48083c26
8 changed files with 94 additions and 122 deletions
+1 -1
View File
@@ -109,7 +109,7 @@ const disconnect = () => {
httpServer?.on('close', resolve); httpServer?.on('close', resolve);
httpServer?.close(); httpServer?.close();
srf.disconnect(); srf.disconnect();
srf.locals.mediaservers.forEach((ms) => ms.disconnect()); srf.locals.mediaservers?.forEach((ms) => ms.disconnect());
}); });
}; };
+43 -34
View File
@@ -221,7 +221,7 @@ class TaskGather extends SttTask {
} catch (err) { } catch (err) {
this.logger.error(err, 'TaskGather:exec error'); this.logger.error(err, 'TaskGather:exec error');
} }
this.removeSpeechListeners(ep); this.removeCustomEventListeners();
} }
kill(cs) { kill(cs) {
@@ -261,7 +261,7 @@ class TaskGather extends SttTask {
else if (this.input.includes('digits')) { else if (this.input.includes('digits')) {
if (this.digitBuffer.length === 0 && this.needsStt) { if (this.digitBuffer.length === 0 && this.needsStt) {
// DTMF is higher priority than STT. // DTMF is higher priority than STT.
this.removeSpeechListeners(ep); this.removeCustomEventListeners();
ep.stopTranscription({ ep.stopTranscription({
vendor: this.vendor, vendor: this.vendor,
bugname: this.bugname, bugname: this.bugname,
@@ -305,33 +305,37 @@ class TaskGather extends SttTask {
switch (this.vendor) { switch (this.vendor) {
case 'google': case 'google':
this.bugname = `${this.bugname_prefix}google_transcribe`; this.bugname = `${this.bugname_prefix}google_transcribe`;
ep.addCustomEventListener(GoogleTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(
ep.addCustomEventListener(GoogleTranscriptionEvents.EndOfUtterance, this._onEndOfUtterance.bind(this, cs, ep)); ep, GoogleTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(GoogleTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep)); this.addCustomEventListener(
ep, GoogleTranscriptionEvents.EndOfUtterance, this._onEndOfUtterance.bind(this, cs, ep));
this.addCustomEventListener(
ep, GoogleTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep));
break; break;
case 'aws': case 'aws':
case 'polly': case 'polly':
this.bugname = `${this.bugname_prefix}aws_transcribe`; this.bugname = `${this.bugname_prefix}aws_transcribe`;
ep.addCustomEventListener(AwsTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(ep, AwsTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(AwsTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep)); this.addCustomEventListener(ep, AwsTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep));
break; break;
case 'microsoft': case 'microsoft':
this.bugname = `${this.bugname_prefix}azure_transcribe`; this.bugname = `${this.bugname_prefix}azure_transcribe`;
ep.addCustomEventListener(AzureTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(
ep.addCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected, ep, AzureTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
this.addCustomEventListener(ep, AzureTranscriptionEvents.NoSpeechDetected,
this._onNoSpeechDetected.bind(this, cs, ep)); this._onNoSpeechDetected.bind(this, cs, ep));
ep.addCustomEventListener(AzureTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep)); this.addCustomEventListener(ep, AzureTranscriptionEvents.VadDetected, this._onVadDetected.bind(this, cs, ep));
break; break;
case 'nuance': case 'nuance':
this.bugname = `${this.bugname_prefix}nuance_transcribe`; this.bugname = `${this.bugname_prefix}nuance_transcribe`;
ep.addCustomEventListener(NuanceTranscriptionEvents.Transcription, this.addCustomEventListener(ep, NuanceTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep)); this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(NuanceTranscriptionEvents.StartOfSpeech, this.addCustomEventListener(ep, NuanceTranscriptionEvents.StartOfSpeech,
this._onStartOfSpeech.bind(this, cs, ep)); this._onStartOfSpeech.bind(this, cs, ep));
ep.addCustomEventListener(NuanceTranscriptionEvents.TranscriptionComplete, this.addCustomEventListener(ep, NuanceTranscriptionEvents.TranscriptionComplete,
this._onTranscriptionComplete.bind(this, cs, ep)); this._onTranscriptionComplete.bind(this, cs, ep));
ep.addCustomEventListener(NuanceTranscriptionEvents.VadDetected, this.addCustomEventListener(ep, NuanceTranscriptionEvents.VadDetected,
this._onVadDetected.bind(this, cs, ep)); this._onVadDetected.bind(this, cs, ep));
/* stall timers until prompt finishes playing */ /* stall timers until prompt finishes playing */
@@ -342,9 +346,10 @@ class TaskGather extends SttTask {
case 'deepgram': case 'deepgram':
this.bugname = `${this.bugname_prefix}deepgram_transcribe`; this.bugname = `${this.bugname_prefix}deepgram_transcribe`;
ep.addCustomEventListener(DeepgramTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(
ep.addCustomEventListener(DeepgramTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep)); ep, DeepgramTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, DeepgramTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
this.addCustomEventListener(ep, DeepgramTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep)); this._onVendorConnectFailure.bind(this, cs, ep));
/* if app sets deepgramOptions.utteranceEndMs they essentially want continuous asr */ /* if app sets deepgramOptions.utteranceEndMs they essentially want continuous asr */
@@ -353,12 +358,14 @@ class TaskGather extends SttTask {
case 'soniox': case 'soniox':
this.bugname = `${this.bugname_prefix}soniox_transcribe`; this.bugname = `${this.bugname_prefix}soniox_transcribe`;
ep.addCustomEventListener(SonioxTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(
ep, SonioxTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
break; break;
case 'cobalt': case 'cobalt':
this.bugname = `${this.bugname_prefix}cobalt_transcribe`; this.bugname = `${this.bugname_prefix}cobalt_transcribe`;
ep.addCustomEventListener(CobaltTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(
ep, CobaltTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
/* cobalt doesnt have language, it has model, which is required */ /* cobalt doesnt have language, it has model, which is required */
if (!this.data.recognizer.model) { if (!this.data.recognizer.model) {
@@ -388,21 +395,21 @@ class TaskGather extends SttTask {
case 'ibm': case 'ibm':
this.bugname = `${this.bugname_prefix}ibm_transcribe`; this.bugname = `${this.bugname_prefix}ibm_transcribe`;
ep.addCustomEventListener(IbmTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(ep, IbmTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(IbmTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep)); this.addCustomEventListener(ep, IbmTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
ep.addCustomEventListener(IbmTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, IbmTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep)); this._onVendorConnectFailure.bind(this, cs, ep));
break; break;
case 'nvidia': case 'nvidia':
this.bugname = `${this.bugname_prefix}nvidia_transcribe`; this.bugname = `${this.bugname_prefix}nvidia_transcribe`;
ep.addCustomEventListener(NvidiaTranscriptionEvents.Transcription, this.addCustomEventListener(ep, NvidiaTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep)); this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(NvidiaTranscriptionEvents.StartOfSpeech, this.addCustomEventListener(ep, NvidiaTranscriptionEvents.StartOfSpeech,
this._onStartOfSpeech.bind(this, cs, ep)); this._onStartOfSpeech.bind(this, cs, ep));
ep.addCustomEventListener(NvidiaTranscriptionEvents.TranscriptionComplete, this.addCustomEventListener(ep, NvidiaTranscriptionEvents.TranscriptionComplete,
this._onTranscriptionComplete.bind(this, cs, ep)); this._onTranscriptionComplete.bind(this, cs, ep));
ep.addCustomEventListener(NvidiaTranscriptionEvents.VadDetected, this.addCustomEventListener(ep, NvidiaTranscriptionEvents.VadDetected,
this._onVadDetected.bind(this, cs, ep)); this._onVadDetected.bind(this, cs, ep));
/* I think nvidia has this (??) - stall timers until prompt finishes playing */ /* I think nvidia has this (??) - stall timers until prompt finishes playing */
@@ -413,19 +420,21 @@ class TaskGather extends SttTask {
case 'assemblyai': case 'assemblyai':
this.bugname = `${this.bugname_prefix}assemblyai_transcribe`; this.bugname = `${this.bugname_prefix}assemblyai_transcribe`;
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Transcription, this.addCustomEventListener(ep, AssemblyAiTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep)); this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep)); this.addCustomEventListener(
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Error, this._onVendorError.bind(this, cs, ep)); ep, AssemblyAiTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, AssemblyAiTranscriptionEvents.Error, this._onVendorError.bind(this, cs, ep));
this.addCustomEventListener(ep, AssemblyAiTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep)); this._onVendorConnectFailure.bind(this, cs, ep));
break; break;
default: default:
if (this.vendor.startsWith('custom:')) { if (this.vendor.startsWith('custom:')) {
this.bugname = `${this.bugname_prefix}${this.vendor}_transcribe`; this.bugname = `${this.bugname_prefix}${this.vendor}_transcribe`;
ep.addCustomEventListener(JambonzTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep)); this.addCustomEventListener(
ep.addCustomEventListener(JambonzTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep)); ep, JambonzTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
ep.addCustomEventListener(JambonzTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, JambonzTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
this.addCustomEventListener(ep, JambonzTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep)); this._onVendorConnectFailure.bind(this, cs, ep));
break; break;
} }
@@ -437,7 +446,7 @@ class TaskGather extends SttTask {
} }
/* common handler for all stt engine errors */ /* common handler for all stt engine errors */
ep.addCustomEventListener(JambonzTranscriptionEvents.Error, this._onJambonzError.bind(this, cs, ep)); this.addCustomEventListener(ep, JambonzTranscriptionEvents.Error, this._onJambonzError.bind(this, cs, ep));
await ep.set(opts) await ep.set(opts)
.catch((err) => this.logger.info(err, 'Error setting channel variables')); .catch((err) => this.logger.info(err, 'Error setting channel variables'));
} }
+10 -3
View File
@@ -14,17 +14,15 @@ class SttTask extends Task {
const { const {
setChannelVarsForStt, setChannelVarsForStt,
normalizeTranscription, normalizeTranscription,
removeSpeechListeners,
setSpeechCredentialsAtRuntime, setSpeechCredentialsAtRuntime,
compileSonioxTranscripts, compileSonioxTranscripts,
consolidateTranscripts consolidateTranscripts
} = require('../utils/transcription-utils')(logger); } = require('../utils/transcription-utils')(logger);
this.setChannelVarsForStt = setChannelVarsForStt; this.setChannelVarsForStt = setChannelVarsForStt;
this.normalizeTranscription = normalizeTranscription; this.normalizeTranscription = normalizeTranscription;
this.removeSpeechListeners = removeSpeechListeners;
this.compileSonioxTranscripts = compileSonioxTranscripts; this.compileSonioxTranscripts = compileSonioxTranscripts;
this.consolidateTranscripts = consolidateTranscripts; this.consolidateTranscripts = consolidateTranscripts;
this.eventHandlers = [];
this.isHandledByPrimaryProvider = true; this.isHandledByPrimaryProvider = true;
if (this.data.recognizer) { if (this.data.recognizer) {
const recognizer = this.data.recognizer; const recognizer = this.data.recognizer;
@@ -140,6 +138,15 @@ class SttTask extends Task {
} }
} }
addCustomEventListener(ep, event, handler) {
this.eventHandlers.push({ep, event, handler});
ep.addCustomEventListener(event, handler);
}
removeCustomEventListeners() {
this.eventHandlers.forEach((h) => h.ep.removeCustomEventListener(h.event, h.handler));
}
async _initSpeechCredentials(cs, vendor, label) { async _initSpeechCredentials(cs, vendor, label) {
const {getNuanceAccessToken, getIbmAccessToken} = cs.srf.locals.dbHelpers; const {getNuanceAccessToken, getIbmAccessToken} = cs.srf.locals.dbHelpers;
let credentials = cs.getSpeechCredentials(vendor, 'stt', label); let credentials = cs.getSpeechCredentials(vendor, 'stt', label);
+28 -27
View File
@@ -80,7 +80,7 @@ class TaskTranscribe extends SttTask {
this.logger.info(err, 'TaskTranscribe:exec - error'); this.logger.info(err, 'TaskTranscribe:exec - error');
this.parentTask && this.parentTask.emit('error', err); this.parentTask && this.parentTask.emit('error', err);
} }
this.removeSpeechListeners(ep); this.removeCustomEventListeners();
} }
async _stopTranscription() { async _stopTranscription() {
@@ -142,43 +142,43 @@ class TaskTranscribe extends SttTask {
switch (this.vendor) { switch (this.vendor) {
case 'google': case 'google':
this.bugname = `${this.bugname_prefix}google_transcribe`; this.bugname = `${this.bugname_prefix}google_transcribe`;
ep.addCustomEventListener(GoogleTranscriptionEvents.Transcription, this.addCustomEventListener(ep, GoogleTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(GoogleTranscriptionEvents.NoAudioDetected, this.addCustomEventListener(ep, GoogleTranscriptionEvents.NoAudioDetected,
this._onNoAudio.bind(this, cs, ep, channel)); this._onNoAudio.bind(this, cs, ep, channel));
ep.addCustomEventListener(GoogleTranscriptionEvents.MaxDurationExceeded, this.addCustomEventListener(ep, GoogleTranscriptionEvents.MaxDurationExceeded,
this._onMaxDurationExceeded.bind(this, cs, ep, channel)); this._onMaxDurationExceeded.bind(this, cs, ep, channel));
break; break;
case 'aws': case 'aws':
case 'polly': case 'polly':
this.bugname = `${this.bugname_prefix}aws_transcribe`; this.bugname = `${this.bugname_prefix}aws_transcribe`;
ep.addCustomEventListener(AwsTranscriptionEvents.Transcription, this.addCustomEventListener(ep, AwsTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(AwsTranscriptionEvents.NoAudioDetected, this.addCustomEventListener(ep, AwsTranscriptionEvents.NoAudioDetected,
this._onNoAudio.bind(this, cs, ep, channel)); this._onNoAudio.bind(this, cs, ep, channel));
ep.addCustomEventListener(AwsTranscriptionEvents.MaxDurationExceeded, this.addCustomEventListener(ep, AwsTranscriptionEvents.MaxDurationExceeded,
this._onMaxDurationExceeded.bind(this, cs, ep, channel)); this._onMaxDurationExceeded.bind(this, cs, ep, channel));
break; break;
case 'microsoft': case 'microsoft':
this.bugname = `${this.bugname_prefix}azure_transcribe`; this.bugname = `${this.bugname_prefix}azure_transcribe`;
ep.addCustomEventListener(AzureTranscriptionEvents.Transcription, this.addCustomEventListener(ep, AzureTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected, this.addCustomEventListener(ep, AzureTranscriptionEvents.NoSpeechDetected,
this._onNoAudio.bind(this, cs, ep, channel)); this._onNoAudio.bind(this, cs, ep, channel));
break; break;
case 'nuance': case 'nuance':
this.bugname = `${this.bugname_prefix}nuance_transcribe`; this.bugname = `${this.bugname_prefix}nuance_transcribe`;
ep.addCustomEventListener(NuanceTranscriptionEvents.Transcription, this.addCustomEventListener(ep, NuanceTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
break; break;
case 'deepgram': case 'deepgram':
this.bugname = `${this.bugname_prefix}deepgram_transcribe`; this.bugname = `${this.bugname_prefix}deepgram_transcribe`;
ep.addCustomEventListener(DeepgramTranscriptionEvents.Transcription, this.addCustomEventListener(ep, DeepgramTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(DeepgramTranscriptionEvents.Connect, this.addCustomEventListener(ep, DeepgramTranscriptionEvents.Connect,
this._onVendorConnect.bind(this, cs, ep)); this._onVendorConnect.bind(this, cs, ep));
ep.addCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, DeepgramTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep, channel)); this._onVendorConnectFailure.bind(this, cs, ep, channel));
/* if app sets deepgramOptions.utteranceEndMs they essentially want continuous asr */ /* if app sets deepgramOptions.utteranceEndMs they essentially want continuous asr */
@@ -187,12 +187,12 @@ class TaskTranscribe extends SttTask {
break; break;
case 'soniox': case 'soniox':
this.bugname = `${this.bugname_prefix}soniox_transcribe`; this.bugname = `${this.bugname_prefix}soniox_transcribe`;
ep.addCustomEventListener(SonioxTranscriptionEvents.Transcription, this.addCustomEventListener(ep, SonioxTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
break; break;
case 'cobalt': case 'cobalt':
this.bugname = `${this.bugname_prefix}cobalt_transcribe`; this.bugname = `${this.bugname_prefix}cobalt_transcribe`;
ep.addCustomEventListener(CobaltTranscriptionEvents.Transcription, this.addCustomEventListener(ep, CobaltTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
/* cobalt doesnt have language, it has model, which is required */ /* cobalt doesnt have language, it has model, which is required */
@@ -222,37 +222,38 @@ class TaskTranscribe extends SttTask {
case 'ibm': case 'ibm':
this.bugname = `${this.bugname_prefix}ibm_transcribe`; this.bugname = `${this.bugname_prefix}ibm_transcribe`;
ep.addCustomEventListener(IbmTranscriptionEvents.Transcription, this.addCustomEventListener(ep, IbmTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(IbmTranscriptionEvents.Connect, this.addCustomEventListener(ep, IbmTranscriptionEvents.Connect,
this._onVendorConnect.bind(this, cs, ep)); this._onVendorConnect.bind(this, cs, ep));
ep.addCustomEventListener(IbmTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, IbmTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep, channel)); this._onVendorConnectFailure.bind(this, cs, ep, channel));
break; break;
case 'nvidia': case 'nvidia':
this.bugname = `${this.bugname_prefix}nvidia_transcribe`; this.bugname = `${this.bugname_prefix}nvidia_transcribe`;
ep.addCustomEventListener(NvidiaTranscriptionEvents.Transcription, this.addCustomEventListener(ep, NvidiaTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
break; break;
case 'assemblyai': case 'assemblyai':
this.bugname = `${this.bugname_prefix}assemblyai_transcribe`; this.bugname = `${this.bugname_prefix}assemblyai_transcribe`;
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Transcription, this.addCustomEventListener(ep, AssemblyAiTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep)); this.addCustomEventListener(ep,
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Error, this._onVendorError.bind(this, cs, ep)); AssemblyAiTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, AssemblyAiTranscriptionEvents.Error, this._onVendorError.bind(this, cs, ep));
this.addCustomEventListener(ep, AssemblyAiTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep, channel)); this._onVendorConnectFailure.bind(this, cs, ep, channel));
break; break;
default: default:
if (this.vendor.startsWith('custom:')) { if (this.vendor.startsWith('custom:')) {
this.bugname = `${this.bugname_prefix}${this.vendor}_transcribe`; this.bugname = `${this.bugname_prefix}${this.vendor}_transcribe`;
ep.addCustomEventListener(JambonzTranscriptionEvents.Transcription, this.addCustomEventListener(ep, JambonzTranscriptionEvents.Transcription,
this._onTranscription.bind(this, cs, ep, channel)); this._onTranscription.bind(this, cs, ep, channel));
ep.addCustomEventListener(JambonzTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep)); this.addCustomEventListener(ep, JambonzTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
ep.addCustomEventListener(JambonzTranscriptionEvents.ConnectFailure, this.addCustomEventListener(ep, JambonzTranscriptionEvents.ConnectFailure,
this._onVendorConnectFailure.bind(this, cs, ep)); this._onVendorConnectFailure.bind(this, cs, ep));
break; break;
} }
@@ -264,7 +265,7 @@ class TaskTranscribe extends SttTask {
} }
/* common handler for all stt engine errors */ /* common handler for all stt engine errors */
ep.addCustomEventListener(JambonzTranscriptionEvents.Error, this._onJambonzError.bind(this, cs, ep)); this.addCustomEventListener(ep, JambonzTranscriptionEvents.Error, this._onJambonzError.bind(this, cs, ep));
await ep.set(opts) await ep.set(opts)
.catch((err) => this.logger.info(err, 'Error setting channel variables')); .catch((err) => this.logger.info(err, 'Error setting channel variables'));
} }
+1 -54
View File
@@ -1,15 +1,5 @@
const { const {
TaskName, TaskName,
AzureTranscriptionEvents,
GoogleTranscriptionEvents,
AwsTranscriptionEvents,
NuanceTranscriptionEvents,
DeepgramTranscriptionEvents,
SonioxTranscriptionEvents,
NvidiaTranscriptionEvents,
CobaltTranscriptionEvents,
JambonzTranscriptionEvents,
AssemblyAiTranscriptionEvents
} = require('./constants.json'); } = require('./constants.json');
const stickyVars = { const stickyVars = {
@@ -615,7 +605,7 @@ module.exports = (logger) => {
...(deepgramOptions.keywords) && ...(deepgramOptions.keywords) &&
{DEEPGRAM_SPEECH_KEYWORDS: deepgramOptions.keywords.join(',')}, {DEEPGRAM_SPEECH_KEYWORDS: deepgramOptions.keywords.join(',')},
...('endpointing' in deepgramOptions) && ...('endpointing' in deepgramOptions) &&
{DEEPGRAM_SPEECH_ENDPOINTING: deepgramOptions.endpointing}, {DEEPGRAM_SPEECH_ENDPOINTING: deepgramOptions.endpointing === false ? 'false' : deepgramOptions.endpointing},
...(deepgramOptions.utteranceEndMs) && ...(deepgramOptions.utteranceEndMs) &&
{DEEPGRAM_SPEECH_UTTERANCE_END_MS: deepgramOptions.utteranceEndMs}, {DEEPGRAM_SPEECH_UTTERANCE_END_MS: deepgramOptions.utteranceEndMs},
...(deepgramOptions.vadTurnoff) && ...(deepgramOptions.vadTurnoff) &&
@@ -755,48 +745,6 @@ module.exports = (logger) => {
return opts; return opts;
}; };
const removeSpeechListeners = (ep) => {
ep.removeCustomEventListener(GoogleTranscriptionEvents.Transcription);
ep.removeCustomEventListener(GoogleTranscriptionEvents.EndOfUtterance);
ep.removeCustomEventListener(GoogleTranscriptionEvents.VadDetected);
ep.removeCustomEventListener(AwsTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AwsTranscriptionEvents.VadDetected);
ep.removeCustomEventListener(AzureTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AzureTranscriptionEvents.NoSpeechDetected);
ep.removeCustomEventListener(AzureTranscriptionEvents.VadDetected);
ep.removeCustomEventListener(NuanceTranscriptionEvents.Transcription);
ep.removeCustomEventListener(NuanceTranscriptionEvents.TranscriptionComplete);
ep.removeCustomEventListener(NuanceTranscriptionEvents.StartOfSpeech);
ep.removeCustomEventListener(NuanceTranscriptionEvents.VadDetected);
ep.removeCustomEventListener(DeepgramTranscriptionEvents.Transcription);
ep.removeCustomEventListener(DeepgramTranscriptionEvents.Connect);
ep.removeCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure);
ep.removeCustomEventListener(SonioxTranscriptionEvents.Transcription);
ep.removeCustomEventListener(CobaltTranscriptionEvents.Transcription);
ep.removeCustomEventListener(CobaltTranscriptionEvents.CompileContext);
ep.removeCustomEventListener(NvidiaTranscriptionEvents.Transcription);
ep.removeCustomEventListener(NvidiaTranscriptionEvents.TranscriptionComplete);
ep.removeCustomEventListener(NvidiaTranscriptionEvents.StartOfSpeech);
ep.removeCustomEventListener(NvidiaTranscriptionEvents.VadDetected);
ep.removeCustomEventListener(JambonzTranscriptionEvents.Transcription);
ep.removeCustomEventListener(JambonzTranscriptionEvents.Connect);
ep.removeCustomEventListener(JambonzTranscriptionEvents.ConnectFailure);
ep.removeCustomEventListener(JambonzTranscriptionEvents.Error);
ep.removeCustomEventListener(AssemblyAiTranscriptionEvents.Transcription);
ep.removeCustomEventListener(AssemblyAiTranscriptionEvents.Connect);
ep.removeCustomEventListener(AssemblyAiTranscriptionEvents.ConnectFailure);
};
const setSpeechCredentialsAtRuntime = (recognizer) => { const setSpeechCredentialsAtRuntime = (recognizer) => {
if (!recognizer) return; if (!recognizer) return;
if (recognizer.vendor === 'nuance') { if (recognizer.vendor === 'nuance') {
@@ -835,7 +783,6 @@ module.exports = (logger) => {
return { return {
normalizeTranscription, normalizeTranscription,
setChannelVarsForStt, setChannelVarsForStt,
removeSpeechListeners,
setSpeechCredentialsAtRuntime, setSpeechCredentialsAtRuntime,
compileSonioxTranscripts, compileSonioxTranscripts,
consolidateTranscripts consolidateTranscripts
+2 -2
View File
@@ -42,7 +42,7 @@ services:
ipv4_address: 172.38.0.7 ipv4_address: 172.38.0.7
drachtio: drachtio:
image: drachtio/drachtio-server:0.8.22 image: drachtio/drachtio-server:latest
restart: always restart: always
command: drachtio --contact "sip:*;transport=udp" --mtu 4096 --address 0.0.0.0 --port 9022 command: drachtio --contact "sip:*;transport=udp" --mtu 4096 --address 0.0.0.0 --port 9022
ports: ports:
@@ -57,7 +57,7 @@ services:
condition: service_healthy condition: service_healthy
freeswitch: freeswitch:
image: drachtio/drachtio-freeswitch-mrf:0.5.6 image: drachtio/drachtio-freeswitch-mrf:latest
restart: always restart: always
command: freeswitch --rtp-range-start 20000 --rtp-range-end 20100 command: freeswitch --rtp-range-start 20000 --rtp-range-end 20100
environment: environment:
+1 -1
View File
@@ -188,7 +188,7 @@ test('\'play\' tests with seekOffset and actionHook', async(t) => {
const seconds = parseInt(obj.body.playback_seconds); const seconds = parseInt(obj.body.playback_seconds);
const milliseconds = parseInt(obj.body.playback_milliseconds); const milliseconds = parseInt(obj.body.playback_milliseconds);
const lastOffsetPos = parseInt(obj.body.playback_last_offset_pos); const lastOffsetPos = parseInt(obj.body.playback_last_offset_pos);
//console.log({obj}, 'lastRequest'); console.log({obj}, 'lastRequest');
t.ok(obj.body.reason === "playCompleted", "play: actionHook success received"); t.ok(obj.body.reason === "playCompleted", "play: actionHook success received");
t.ok(seconds === 2, "playback_seconds: actionHook success received"); t.ok(seconds === 2, "playback_seconds: actionHook success received");
t.ok(milliseconds === 2048, "playback_milliseconds: actionHook success received"); t.ok(milliseconds === 2048, "playback_milliseconds: actionHook success received");
+8
View File
@@ -52,6 +52,7 @@ test('\'transcribe\' test - google', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'),
'transcribe: succeeds when using google credentials'); 'transcribe: succeeds when using google credentials');
@@ -89,6 +90,7 @@ test('\'transcribe\' test - microsoft', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'),
'transcribe: succeeds when using microsoft credentials'); 'transcribe: succeeds when using microsoft credentials');
@@ -126,6 +128,7 @@ test('\'transcribe\' test - aws', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'),
'transcribe: succeeds when using aws credentials'); 'transcribe: succeeds when using aws credentials');
@@ -190,6 +193,7 @@ test('\'transcribe\' test - deepgram config options', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'),
'transcribe: succeeds when using deepgram credentials'); 'transcribe: succeeds when using deepgram credentials');
@@ -230,6 +234,7 @@ test('\'transcribe\' test - deepgram', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'),
'transcribe: succeeds when using deepgram credentials'); 'transcribe: succeeds when using deepgram credentials');
@@ -309,6 +314,7 @@ test('\'transcribe\' test - google with asrTimeout', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().startsWith('i\'d like to speak to customer support'),
'transcribe: succeeds when using google credentials'); 'transcribe: succeeds when using google credentials');
@@ -369,6 +375,7 @@ test('\'transcribe\' test - deepgram config options altLanguages', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'),
'transcribe: succeeds when using deepgram credentials'); 'transcribe: succeeds when using deepgram credentials');
@@ -430,6 +437,7 @@ test('\'transcribe\' test - deepgram config options altLanguages', async(t) => {
// THEN // THEN
await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from); await sippUac('uac-gather-account-creds-success.xml', '172.38.0.10', from);
let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`); let obj = await getJSON(`http://127.0.0.1:3100/lastRequest/${from}_actionHook`);
//console.log(JSON.stringify(obj));
t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'), t.ok(obj.body.speech.alternatives[0].transcript.toLowerCase().includes('like to speak to customer support'),
'transcribe: succeeds when using deepgram credentials'); 'transcribe: succeeds when using deepgram credentials');