fix recognizer/synthesizer label wrongly select between verb and app (#881)

* fix recognizer/synthesizer label wrongly select between verb and application

* fix jslint

* fix ASR cannot fallback

* update tts fallback does not send notification
This commit is contained in:
Hoan Luu Huu
2024-09-11 15:34:52 +07:00
committed by GitHub
parent 3a7cc27d0a
commit e69afc4be4
3 changed files with 35 additions and 23 deletions

View File

@@ -79,10 +79,7 @@ class TaskSay extends TtsTask {
let voice = this.synthesizer.voice && this.synthesizer.voice !== 'default' ? let voice = this.synthesizer.voice && this.synthesizer.voice !== 'default' ?
this.synthesizer.voice : this.synthesizer.voice :
cs.speechSynthesisVoice; cs.speechSynthesisVoice;
// label can be null/empty in synthesizer config, just use application level label if it's default let label = this.taskInlcudeSynthesizer ? this.synthesizer.label : cs.speechSynthesisLabel;
let label = this.synthesizer.label === 'default' ?
cs.speechSynthesisLabel :
this.synthesizer.label;
const fallbackVendor = this.synthesizer.fallbackVendor && this.synthesizer.fallbackVendor !== 'default' ? const fallbackVendor = this.synthesizer.fallbackVendor && this.synthesizer.fallbackVendor !== 'default' ?
this.synthesizer.fallbackVendor : this.synthesizer.fallbackVendor :
@@ -93,10 +90,8 @@ class TaskSay extends TtsTask {
const fallbackVoice = this.synthesizer.fallbackVoice && this.synthesizer.fallbackVoice !== 'default' ? const fallbackVoice = this.synthesizer.fallbackVoice && this.synthesizer.fallbackVoice !== 'default' ?
this.synthesizer.fallbackVoice : this.synthesizer.fallbackVoice :
cs.fallbackSpeechSynthesisVoice; cs.fallbackSpeechSynthesisVoice;
// label can be null/empty in synthesizer config, just use application level label if it's default const fallbackLabel = this.taskInlcudeSynthesizer ?
const fallbackLabel = this.synthesizer.fallbackLabel === 'default' ? this.synthesizer.fallbackLabel : cs.fallbackSpeechSynthesisLabel;
cs.fallbackSpeechSynthesisLabel :
this.synthesizer.fallbackLabel;
if (cs.hasFallbackTts) { if (cs.hasFallbackTts) {
vendor = fallbackVendor; vendor = fallbackVendor;

View File

@@ -24,6 +24,12 @@ class SttTask extends Task {
this.consolidateTranscripts = consolidateTranscripts; this.consolidateTranscripts = consolidateTranscripts;
this.eventHandlers = []; this.eventHandlers = [];
this.isHandledByPrimaryProvider = true; this.isHandledByPrimaryProvider = true;
/**
* Task use taskIncludeRecognizer to identify
* if taskIncludeRecognizer === true, use label from verb.recognizer, even it's empty
* if taskIncludeRecognizer === false, use label from application.recognizer
*/
this.taskIncludeRecognizer = !!this.data.recognizer;
if (this.data.recognizer) { if (this.data.recognizer) {
const recognizer = this.data.recognizer; const recognizer = this.data.recognizer;
this.vendor = recognizer.vendor; this.vendor = recognizer.vendor;
@@ -33,7 +39,6 @@ class SttTask extends Task {
//fallback //fallback
this.fallbackVendor = recognizer.fallbackVendor || 'default'; this.fallbackVendor = recognizer.fallbackVendor || 'default';
this.fallbackLanguage = recognizer.fallbackLanguage || 'default'; this.fallbackLanguage = recognizer.fallbackLanguage || 'default';
// label can be empty and should not have default value.
this.fallbackLabel = recognizer.fallbackLabel; this.fallbackLabel = recognizer.fallbackLabel;
/* let credentials be supplied in the recognizer object at runtime */ /* let credentials be supplied in the recognizer object at runtime */
@@ -82,8 +87,7 @@ class SttTask extends Task {
this.language = cs.speechRecognizerLanguage; this.language = cs.speechRecognizerLanguage;
if (this.data.recognizer) this.data.recognizer.language = this.language; if (this.data.recognizer) this.data.recognizer.language = this.language;
} }
// label can be empty, should not assign application level label if (!this.taskIncludeRecognizer) {
if ('default' === this.label) {
this.label = cs.speechRecognizerLabel; this.label = cs.speechRecognizerLabel;
if (this.data.recognizer) this.data.recognizer.label = this.label; if (this.data.recognizer) this.data.recognizer.label = this.label;
} }
@@ -96,17 +100,21 @@ class SttTask extends Task {
this.fallbackLanguage = cs.fallbackSpeechRecognizerLanguage; this.fallbackLanguage = cs.fallbackSpeechRecognizerLanguage;
if (this.data.recognizer) this.data.recognizer.fallbackLanguage = this.fallbackLanguage; if (this.data.recognizer) this.data.recognizer.fallbackLanguage = this.fallbackLanguage;
} }
// label can be empty, should not assign application level label if (!this.taskIncludeRecognizer) {
if ('default' === this.fallbackLabel) {
this.fallbackLabel = cs.fallbackSpeechRecognizerLabel; this.fallbackLabel = cs.fallbackSpeechRecognizerLabel;
if (this.data.recognizer) this.data.recognizer.fallbackLabel = this.fallbackLabel; if (this.data.recognizer) this.data.recognizer.fallbackLabel = this.fallbackLabel;
} }
// If call is already fallback to 2nd ASR vendor
// use that.
if (cs.hasFallbackAsr) { if (cs.hasFallbackAsr) {
this.vendor = this.fallbackVendor; if (this.taskIncludeRecognizer) {
this.language = this.fallbackLanguage; // reset fallback ASR from previous run if this verb contains data.recognizer.
this.label = this.fallbackLabel; cs.hasFallbackAsr = false;
} else {
this.logger.debug('Call session has fallback to 2nd ASR, use 2nd recognizer configuration');
this.vendor = this.fallbackVendor;
this.language = this.fallbackLanguage;
this.label = this.fallbackLabel;
}
} }
if (!this.data.recognizer.vendor) { if (!this.data.recognizer.vendor) {
this.data.recognizer.vendor = this.vendor; this.data.recognizer.vendor = this.vendor;
@@ -181,7 +189,7 @@ class SttTask extends Task {
vendor, vendor,
target_sid: cs.callSid target_sid: cs.callSid
}).catch((err) => this.logger.info({err}, 'Error generating alert for no stt')); }).catch((err) => this.logger.info({err}, 'Error generating alert for no stt'));
this.notifyTaskDone(); // the ASR might have fallback configuration, should not done task here.
throw new Error(`No speech-to-text service credentials for ${vendor} have been configured`); throw new Error(`No speech-to-text service credentials for ${vendor} have been configured`);
} }
@@ -223,12 +231,12 @@ class SttTask extends Task {
async _initFallback() { async _initFallback() {
assert(this.fallbackVendor, 'fallback failed without fallbackVendor configuration'); assert(this.fallbackVendor, 'fallback failed without fallbackVendor configuration');
this.logger.info(`Failed to use primary STT provider, fallback to ${this.fallbackVendor}`);
this.isHandledByPrimaryProvider = false; this.isHandledByPrimaryProvider = false;
this.cs.hasFallbackAsr = true; this.cs.hasFallbackAsr = true;
this.logger.info(`Failed to use primary STT provider, fallback to ${this.fallbackVendor}`); this.vendor = this.cs.fallbackSpeechRecognizerVendor = this.fallbackVendor;
this.vendor = this.fallbackVendor; this.language = this.cs.fallbackSpeechRecognizerLanguage = this.fallbackLanguage;
this.language = this.fallbackLanguage; this.label = this.cs.fallbackSpeechRecognizerLabel = this.fallbackLabel;
this.label = this.fallbackLabel;
this.data.recognizer.vendor = this.vendor; this.data.recognizer.vendor = this.vendor;
this.data.recognizer.language = this.language; this.data.recognizer.language = this.language;
this.data.recognizer.label = this.label; this.data.recognizer.label = this.label;

View File

@@ -10,6 +10,12 @@ class TtsTask extends Task {
this.preconditions = TaskPreconditions.Endpoint; this.preconditions = TaskPreconditions.Endpoint;
this.earlyMedia = this.data.earlyMedia === true || (parentTask && parentTask.earlyMedia); this.earlyMedia = this.data.earlyMedia === true || (parentTask && parentTask.earlyMedia);
/**
* Task use taskInlcudeSynthesizer to identify
* if taskInlcudeSynthesizer === true, use label from verb.synthesizer, even it's empty
* if taskInlcudeSynthesizer === false, use label from application.synthesizer
*/
this.taskInlcudeSynthesizer = !!this.data.synthesizer;
this.synthesizer = this.data.synthesizer || {}; this.synthesizer = this.data.synthesizer || {};
this.disableTtsCache = this.data.disableTtsCache; this.disableTtsCache = this.data.disableTtsCache;
this.options = this.synthesizer.options || {}; this.options = this.synthesizer.options || {};
@@ -45,6 +51,9 @@ class TtsTask extends Task {
const salt = cs.callSid; const salt = cs.callSid;
let credentials = cs.getSpeechCredentials(vendor, 'tts', label); let credentials = cs.getSpeechCredentials(vendor, 'tts', label);
if (!credentials) {
throw new Error(`No text-to-speech service credentials for ${vendor} with labels: ${label} have been configured`);
}
/* parse Nuance voices into name and model */ /* parse Nuance voices into name and model */
let model; let model;
if (vendor === 'nuance' && voice) { if (vendor === 'nuance' && voice) {