mirror of
https://github.com/jambonz/jambonz-feature-server.git
synced 2026-02-15 10:49:07 +00:00
Compare commits
6 Commits
v0.8.5-rc1
...
v0.8.5-rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31559cbb3b | ||
|
|
1156bae2de | ||
|
|
c6c599ab99 | ||
|
|
4d0f0fe75f | ||
|
|
6d625d87ad | ||
|
|
7fee2ba2dc |
@@ -23,7 +23,8 @@ module.exports = function(srf, logger) {
|
|||||||
lookupAppBySid,
|
lookupAppBySid,
|
||||||
lookupAppByRealm,
|
lookupAppByRealm,
|
||||||
lookupAppByTeamsTenant,
|
lookupAppByTeamsTenant,
|
||||||
registrar
|
registrar,
|
||||||
|
lookupClientByAccountAndUsername
|
||||||
} = srf.locals.dbHelpers;
|
} = srf.locals.dbHelpers;
|
||||||
const {
|
const {
|
||||||
writeAlerts,
|
writeAlerts,
|
||||||
@@ -35,6 +36,7 @@ module.exports = function(srf, logger) {
|
|||||||
const callId = req.get('Call-ID');
|
const callId = req.get('Call-ID');
|
||||||
const uri = parseUri(req.uri);
|
const uri = parseUri(req.uri);
|
||||||
logger.info({
|
logger.info({
|
||||||
|
uri,
|
||||||
callId,
|
callId,
|
||||||
callingNumber: req.callingNumber,
|
callingNumber: req.callingNumber,
|
||||||
calledNumber: req.calledNumber
|
calledNumber: req.calledNumber
|
||||||
@@ -47,10 +49,17 @@ module.exports = function(srf, logger) {
|
|||||||
const account_sid = req.get('X-Account-Sid');
|
const account_sid = req.get('X-Account-Sid');
|
||||||
req.locals = {callSid, account_sid, callId};
|
req.locals = {callSid, account_sid, callId};
|
||||||
|
|
||||||
if (req.has('X-Authenticated-User')) req.locals.originatingUser = req.get('X-Authenticated-User');
|
let clientDb = null;
|
||||||
|
if (req.has('X-Authenticated-User')) {
|
||||||
|
req.locals.originatingUser = req.get('X-Authenticated-User');
|
||||||
|
const arr = /^(.*)@(.*)/.exec(req.locals.originatingUser);
|
||||||
|
if (arr) {
|
||||||
|
[clientDb] = await lookupClientByAccountAndUsername(account_sid, arr[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check for call to application
|
// check for call to application
|
||||||
if (uri.user.startsWith('app-') && req.locals.originatingUser) {
|
if (uri.user?.startsWith('app-') && req.locals.originatingUser && clientDb.allow_direct_app_calling) {
|
||||||
const application_sid = uri.user.match(/app-(.*)/)[1];
|
const application_sid = uri.user.match(/app-(.*)/)[1];
|
||||||
logger.debug(`got application from Request URI header: ${application_sid}`);
|
logger.debug(`got application from Request URI header: ${application_sid}`);
|
||||||
req.locals.application_sid = application_sid;
|
req.locals.application_sid = application_sid;
|
||||||
@@ -60,13 +69,13 @@ module.exports = function(srf, logger) {
|
|||||||
req.locals.application_sid = application_sid;
|
req.locals.application_sid = application_sid;
|
||||||
}
|
}
|
||||||
// check for call to queue
|
// check for call to queue
|
||||||
if (uri.user.startsWith('queue-') && req.locals.originatingUser) {
|
if (uri.user?.startsWith('queue-') && req.locals.originatingUser && clientDb.allow_direct_queue_calling) {
|
||||||
const queue_name = uri.user.match(/queue-(.*)/)[1];
|
const queue_name = uri.user.match(/queue-(.*)/)[1];
|
||||||
logger.debug(`got Queue from Request URI header: ${queue_name}`);
|
logger.debug(`got Queue from Request URI header: ${queue_name}`);
|
||||||
req.locals.queue_name = queue_name;
|
req.locals.queue_name = queue_name;
|
||||||
}
|
}
|
||||||
// check for call to registered user
|
// check for call to registered user
|
||||||
if (!JAMBONES_DISABLE_DIRECT_P2P_CALL && req.locals.originatingUser) {
|
if (!JAMBONES_DISABLE_DIRECT_P2P_CALL && req.locals.originatingUser && clientDb.allow_direct_user_calling) {
|
||||||
const arr = /^(.*)@(.*)/.exec(req.locals.originatingUser);
|
const arr = /^(.*)@(.*)/.exec(req.locals.originatingUser);
|
||||||
if (arr) {
|
if (arr) {
|
||||||
const sipRealm = arr[2];
|
const sipRealm = arr[2];
|
||||||
|
|||||||
@@ -835,6 +835,11 @@ class CallSession extends Emitter {
|
|||||||
api_key: credential.api_key,
|
api_key: credential.api_key,
|
||||||
model_id: credential.model_id
|
model_id: credential.model_id
|
||||||
};
|
};
|
||||||
|
} else if ('assemblyai' === vendor) {
|
||||||
|
return {
|
||||||
|
speech_credential_sid: credential.speech_credential_sid,
|
||||||
|
api_key: credential.api_key
|
||||||
|
};
|
||||||
} else if (vendor.startsWith('custom:')) {
|
} else if (vendor.startsWith('custom:')) {
|
||||||
return {
|
return {
|
||||||
speech_credential_sid: credential.speech_credential_sid,
|
speech_credential_sid: credential.speech_credential_sid,
|
||||||
|
|||||||
@@ -58,13 +58,13 @@ class Dialogflow extends Task {
|
|||||||
this.vendor = this.data.tts.vendor || 'default';
|
this.vendor = this.data.tts.vendor || 'default';
|
||||||
this.language = this.data.tts.language || 'default';
|
this.language = this.data.tts.language || 'default';
|
||||||
this.voice = this.data.tts.voice || 'default';
|
this.voice = this.data.tts.voice || 'default';
|
||||||
this.speechSynthesisLabel = this.data.tts.label || 'default';
|
this.speechSynthesisLabel = this.data.tts.label;
|
||||||
|
|
||||||
// fallback tts
|
// fallback tts
|
||||||
this.fallbackVendor = this.data.tts.fallbackVendor || 'default';
|
this.fallbackVendor = this.data.tts.fallbackVendor || 'default';
|
||||||
this.fallbackLanguage = this.data.tts.fallbackLanguage || 'default';
|
this.fallbackLanguage = this.data.tts.fallbackLanguage || 'default';
|
||||||
this.fallbackVoice = this.data.tts.fallbackLanguage || 'default';
|
this.fallbackVoice = this.data.tts.fallbackLanguage || 'default';
|
||||||
this.fallbackLabel = this.data.tts.fallbackLabel || 'default';
|
this.fallbackLabel = this.data.tts.fallbackLabel;
|
||||||
}
|
}
|
||||||
this.bargein = this.data.bargein;
|
this.bargein = this.data.bargein;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,9 @@ const {
|
|||||||
CobaltTranscriptionEvents,
|
CobaltTranscriptionEvents,
|
||||||
IbmTranscriptionEvents,
|
IbmTranscriptionEvents,
|
||||||
NvidiaTranscriptionEvents,
|
NvidiaTranscriptionEvents,
|
||||||
JambonzTranscriptionEvents
|
JambonzTranscriptionEvents,
|
||||||
} = require('../utils/constants');
|
AssemblyAiTranscriptionEvents
|
||||||
|
} = require('../utils/constants.json');
|
||||||
const {
|
const {
|
||||||
JAMBONES_GATHER_EARLY_HINTS_MATCH,
|
JAMBONES_GATHER_EARLY_HINTS_MATCH,
|
||||||
JAMBONZ_GATHER_EARLY_HINTS_MATCH,
|
JAMBONZ_GATHER_EARLY_HINTS_MATCH,
|
||||||
@@ -392,9 +393,9 @@ class TaskGather extends SttTask {
|
|||||||
case 'deepgram':
|
case 'deepgram':
|
||||||
this.bugname = 'deepgram_transcribe';
|
this.bugname = 'deepgram_transcribe';
|
||||||
ep.addCustomEventListener(DeepgramTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
ep.addCustomEventListener(DeepgramTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(DeepgramTranscriptionEvents.Connect, this._onDeepgramConnect.bind(this, cs, ep));
|
ep.addCustomEventListener(DeepgramTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure,
|
ep.addCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure,
|
||||||
this._onDeepGramConnectFailure.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 */
|
||||||
if (opts.DEEPGRAM_SPEECH_UTTERANCE_END_MS) this.isContinuousAsr = true;
|
if (opts.DEEPGRAM_SPEECH_UTTERANCE_END_MS) this.isContinuousAsr = true;
|
||||||
@@ -438,9 +439,9 @@ class TaskGather extends SttTask {
|
|||||||
case 'ibm':
|
case 'ibm':
|
||||||
this.bugname = 'ibm_transcribe';
|
this.bugname = 'ibm_transcribe';
|
||||||
ep.addCustomEventListener(IbmTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
ep.addCustomEventListener(IbmTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(IbmTranscriptionEvents.Connect, this._onIbmConnect.bind(this, cs, ep));
|
ep.addCustomEventListener(IbmTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(IbmTranscriptionEvents.ConnectFailure,
|
ep.addCustomEventListener(IbmTranscriptionEvents.ConnectFailure,
|
||||||
this._onIbmConnectFailure.bind(this, cs, ep));
|
this._onVendorConnectFailure.bind(this, cs, ep));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'nvidia':
|
case 'nvidia':
|
||||||
@@ -460,13 +461,22 @@ class TaskGather extends SttTask {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'assemblyai':
|
||||||
|
this.bugname = 'assemblyai_transcribe';
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Transcription,
|
||||||
|
this._onTranscription.bind(this, cs, ep));
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Error, this._onVendorError.bind(this, cs, ep));
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.ConnectFailure,
|
||||||
|
this._onVendorConnectFailure.bind(this, cs, ep));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (this.vendor.startsWith('custom:')) {
|
if (this.vendor.startsWith('custom:')) {
|
||||||
this.bugname = `${this.vendor}_transcribe`;
|
this.bugname = `${this.vendor}_transcribe`;
|
||||||
ep.addCustomEventListener(JambonzTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
ep.addCustomEventListener(JambonzTranscriptionEvents.Transcription, this._onTranscription.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(JambonzTranscriptionEvents.Connect, this._onJambonzConnect.bind(this, cs, ep));
|
ep.addCustomEventListener(JambonzTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(JambonzTranscriptionEvents.ConnectFailure,
|
ep.addCustomEventListener(JambonzTranscriptionEvents.ConnectFailure,
|
||||||
this._onJambonzConnectFailure.bind(this, cs, ep));
|
this._onVendorConnectFailure.bind(this, cs, ep));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -788,12 +798,6 @@ class TaskGather extends SttTask {
|
|||||||
_onTranscriptionComplete(cs, ep) {
|
_onTranscriptionComplete(cs, ep) {
|
||||||
this.logger.debug('TaskGather:_onTranscriptionComplete');
|
this.logger.debug('TaskGather:_onTranscriptionComplete');
|
||||||
}
|
}
|
||||||
_onDeepgramConnect(_cs, _ep) {
|
|
||||||
this.logger.debug('TaskGather:_onDeepgramConnect');
|
|
||||||
}
|
|
||||||
_onJambonzConnect(_cs, _ep) {
|
|
||||||
this.logger.debug('TaskGather:_onJambonzConnect');
|
|
||||||
}
|
|
||||||
async _onJambonzError(cs, ep, evt) {
|
async _onJambonzError(cs, ep, evt) {
|
||||||
this.logger.info({evt}, 'TaskGather:_onJambonzError');
|
this.logger.info({evt}, 'TaskGather:_onJambonzError');
|
||||||
if (this.isHandledByPrimaryProvider && this.fallbackVendor) {
|
if (this.isHandledByPrimaryProvider && this.fallbackVendor) {
|
||||||
@@ -827,54 +831,16 @@ class TaskGather extends SttTask {
|
|||||||
this.notifyError({msg: 'ASR error', details:`Custom speech vendor ${this.vendor} error: ${evt.error}`});
|
this.notifyError({msg: 'ASR error', details:`Custom speech vendor ${this.vendor} error: ${evt.error}`});
|
||||||
}
|
}
|
||||||
|
|
||||||
_onDeepGramConnectFailure(cs, _ep, evt) {
|
_onVendorConnectFailure(cs, _ep, evt) {
|
||||||
const {reason} = evt;
|
super._onVendorConnectFailure(cs, _ep, evt);
|
||||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
|
||||||
this.logger.info({evt}, 'TaskGather:_onDeepgramConnectFailure');
|
|
||||||
writeAlerts({
|
|
||||||
account_sid: cs.accountSid,
|
|
||||||
alert_type: AlertType.STT_FAILURE,
|
|
||||||
message: `Failed connecting to Deepgram speech recognizer: ${reason}`,
|
|
||||||
vendor: 'deepgram',
|
|
||||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for deepgram connection failure'));
|
|
||||||
this.notifyError({msg: 'ASR error', details:`Failed connecting to speech vendor deepgram: ${reason}`});
|
|
||||||
this.notifyTaskDone();
|
|
||||||
}
|
|
||||||
_onJambonzConnectFailure(cs, _ep, evt) {
|
|
||||||
const {reason} = evt;
|
|
||||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
|
||||||
this.logger.info({evt}, 'TaskGather:_onJambonzConnectFailure');
|
|
||||||
writeAlerts({
|
|
||||||
account_sid: cs.accountSid,
|
|
||||||
alert_type: AlertType.STT_FAILURE,
|
|
||||||
message: `Failed connecting to ${this.vendor} speech recognizer: ${reason}`,
|
|
||||||
vendor: this.vendor,
|
|
||||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for jambonz custom connection failure'));
|
|
||||||
this.notifyError({msg: 'ASR error', details:`Failed connecting to speech vendor ${this.vendor}: ${reason}`});
|
|
||||||
this.notifyTaskDone();
|
this.notifyTaskDone();
|
||||||
}
|
}
|
||||||
|
|
||||||
_onIbmConnect(_cs, _ep) {
|
_onVendorError(cs, _ep, evt) {
|
||||||
this.logger.debug('TaskGather:_onIbmConnect');
|
super._onVendorError(cs, _ep, evt);
|
||||||
|
this._resolve('stt-error', evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
_onIbmConnectFailure(cs, _ep, evt) {
|
|
||||||
const {reason} = evt;
|
|
||||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
|
||||||
this.logger.info({evt}, 'TaskGather:_onIbmConnectFailure');
|
|
||||||
writeAlerts({
|
|
||||||
account_sid: cs.accountSid,
|
|
||||||
alert_type: AlertType.STT_FAILURE,
|
|
||||||
message: `Failed connecting to IBM watson speech recognizer: ${reason}`,
|
|
||||||
vendor: 'ibm',
|
|
||||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for IBM connection failure'));
|
|
||||||
this.notifyError({msg: 'ASR error', details:`Failed connecting to speech vendor IBM: ${reason}`});
|
|
||||||
this.notifyTaskDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
_onIbmError(cs, _ep, evt) {
|
|
||||||
this.logger.info({evt}, 'TaskGather:_onIbmError'); }
|
|
||||||
|
|
||||||
_onVadDetected(cs, ep) {
|
_onVadDetected(cs, ep) {
|
||||||
if (this.bargein && this.minBargeinWordCount === 0) {
|
if (this.bargein && this.minBargeinWordCount === 0) {
|
||||||
this.logger.debug('TaskGather:_onVadDetected');
|
this.logger.debug('TaskGather:_onVadDetected');
|
||||||
@@ -948,6 +914,13 @@ class TaskGather extends SttTask {
|
|||||||
await this.performAction({reason: 'timeout'});
|
await this.performAction({reason: 'timeout'});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (reason.startsWith('stt-error')) {
|
||||||
|
if (this.parentTask) this.parentTask.emit('stt-error', evt);
|
||||||
|
else {
|
||||||
|
this.emit('stt-error', evt);
|
||||||
|
await this.performAction({reason: 'error', details: evt.error});
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) { /*already logged error*/ }
|
} catch (err) { /*already logged error*/ }
|
||||||
this.notifyTaskDone();
|
this.notifyTaskDone();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,6 +148,36 @@ class SttTask extends Task {
|
|||||||
const dgOptions = this.data.recognizer.deepgramOptions = this.data.recognizer.deepgramOptions || {};
|
const dgOptions = this.data.recognizer.deepgramOptions = this.data.recognizer.deepgramOptions || {};
|
||||||
dgOptions.utteranceEndMs = dgOptions.utteranceEndMs || asrTimeout;
|
dgOptions.utteranceEndMs = dgOptions.utteranceEndMs || asrTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onVendorConnect(_cs, _ep) {
|
||||||
|
this.logger.debug(`TaskGather:_on${this.vendor}Connect`);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onVendorError(cs, _ep, evt) {
|
||||||
|
this.logger.info({evt}, `${this.name}:_on${this.vendor}Error`);
|
||||||
|
const {writeAlerts, AlertType} = cs.srf.locals;
|
||||||
|
writeAlerts({
|
||||||
|
account_sid: cs.accountSid,
|
||||||
|
alert_type: AlertType.STT_FAILURE,
|
||||||
|
message: 'STT failure reported by vendor',
|
||||||
|
detail: evt.error,
|
||||||
|
vendor: this.vendor,
|
||||||
|
}).catch((err) => this.logger.info({err}, `Error generating alert for ${this.vendor} connection failure`));
|
||||||
|
this.notifyError({msg: 'ASR error', details:`Failed connecting to speech vendor ${this.vendor}: ${evt.error}`});
|
||||||
|
}
|
||||||
|
|
||||||
|
_onVendorConnectFailure(cs, _ep, evt) {
|
||||||
|
const {reason} = evt;
|
||||||
|
const {writeAlerts, AlertType} = cs.srf.locals;
|
||||||
|
this.logger.info({evt}, `${this.name}:_on${this.vendor}ConnectFailure`);
|
||||||
|
writeAlerts({
|
||||||
|
account_sid: cs.accountSid,
|
||||||
|
alert_type: AlertType.STT_FAILURE,
|
||||||
|
message: `Failed connecting to ${this.vendor} speech recognizer: ${reason}`,
|
||||||
|
vendor: this.vendor,
|
||||||
|
}).catch((err) => this.logger.info({err}, `Error generating alert for ${this.vendor} connection failure`));
|
||||||
|
this.notifyError({msg: 'ASR error', details:`Failed connecting to speech vendor ${this.vendor}: ${reason}`});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SttTask;
|
module.exports = SttTask;
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ const {
|
|||||||
IbmTranscriptionEvents,
|
IbmTranscriptionEvents,
|
||||||
NvidiaTranscriptionEvents,
|
NvidiaTranscriptionEvents,
|
||||||
JambonzTranscriptionEvents,
|
JambonzTranscriptionEvents,
|
||||||
TranscribeStatus
|
TranscribeStatus,
|
||||||
} = require('../utils/constants');
|
AssemblyAiTranscriptionEvents
|
||||||
|
} = require('../utils/constants.json');
|
||||||
const { normalizeJambones } = require('@jambonz/verb-specifications');
|
const { normalizeJambones } = require('@jambonz/verb-specifications');
|
||||||
const SttTask = require('./stt-task');
|
const SttTask = require('./stt-task');
|
||||||
|
|
||||||
@@ -228,9 +229,9 @@ class TaskTranscribe extends SttTask {
|
|||||||
ep.addCustomEventListener(DeepgramTranscriptionEvents.Transcription,
|
ep.addCustomEventListener(DeepgramTranscriptionEvents.Transcription,
|
||||||
this._onTranscription.bind(this, cs, ep, channel));
|
this._onTranscription.bind(this, cs, ep, channel));
|
||||||
ep.addCustomEventListener(DeepgramTranscriptionEvents.Connect,
|
ep.addCustomEventListener(DeepgramTranscriptionEvents.Connect,
|
||||||
this._onDeepgramConnect.bind(this, cs, ep, channel));
|
this._onVendorConnect.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure,
|
ep.addCustomEventListener(DeepgramTranscriptionEvents.ConnectFailure,
|
||||||
this._onDeepGramConnectFailure.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 */
|
||||||
if (opts.DEEPGRAM_SPEECH_UTTERANCE_END_MS) this.isContinuousAsr = true;
|
if (opts.DEEPGRAM_SPEECH_UTTERANCE_END_MS) this.isContinuousAsr = true;
|
||||||
@@ -276,9 +277,9 @@ class TaskTranscribe extends SttTask {
|
|||||||
ep.addCustomEventListener(IbmTranscriptionEvents.Transcription,
|
ep.addCustomEventListener(IbmTranscriptionEvents.Transcription,
|
||||||
this._onTranscription.bind(this, cs, ep, channel));
|
this._onTranscription.bind(this, cs, ep, channel));
|
||||||
ep.addCustomEventListener(IbmTranscriptionEvents.Connect,
|
ep.addCustomEventListener(IbmTranscriptionEvents.Connect,
|
||||||
this._onIbmConnect.bind(this, cs, ep, channel));
|
this._onVendorConnect.bind(this, cs, ep));
|
||||||
ep.addCustomEventListener(IbmTranscriptionEvents.ConnectFailure,
|
ep.addCustomEventListener(IbmTranscriptionEvents.ConnectFailure,
|
||||||
this._onIbmConnectFailure.bind(this, cs, ep, channel));
|
this._onVendorConnectFailure.bind(this, cs, ep, channel));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'nvidia':
|
case 'nvidia':
|
||||||
@@ -293,6 +294,16 @@ class TaskTranscribe extends SttTask {
|
|||||||
this._onVadDetected.bind(this, cs, ep));
|
this._onVadDetected.bind(this, cs, ep));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'assemblyai':
|
||||||
|
this.bugname = 'assemblyai_transcribe';
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Transcription,
|
||||||
|
this._onTranscription.bind(this, cs, ep, channel));
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Connect, this._onVendorConnect.bind(this, cs, ep));
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.Error, this._onVendorError.bind(this, cs, ep));
|
||||||
|
ep.addCustomEventListener(AssemblyAiTranscriptionEvents.ConnectFailure,
|
||||||
|
this._onVendorConnectFailure.bind(this, cs, ep, channel));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (this.vendor.startsWith('custom:')) {
|
if (this.vendor.startsWith('custom:')) {
|
||||||
this.bugname = `${this.vendor}_transcribe`;
|
this.bugname = `${this.vendor}_transcribe`;
|
||||||
@@ -480,78 +491,7 @@ class TaskTranscribe extends SttTask {
|
|||||||
this._timer = null;
|
this._timer = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_onDeepgramConnect(_cs, _ep) {
|
|
||||||
this.logger.debug('TaskTranscribe:_onDeepgramConnect');
|
|
||||||
}
|
|
||||||
|
|
||||||
_onDeepGramConnectFailure(cs, _ep, channel, evt) {
|
|
||||||
const {reason} = evt;
|
|
||||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
|
||||||
this.logger.info({evt}, 'TaskTranscribe:_onDeepgramConnectFailure');
|
|
||||||
writeAlerts({
|
|
||||||
account_sid: cs.accountSid,
|
|
||||||
alert_type: AlertType.STT_FAILURE,
|
|
||||||
message: `Failed connecting to Deepgram speech recognizer: ${reason}`,
|
|
||||||
vendor: 'deepgram',
|
|
||||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for deepgram connection failure'));
|
|
||||||
this.notifyError(`Failed connecting to speech vendor deepgram: ${reason}`);
|
|
||||||
|
|
||||||
if (this.childSpan[channel - 1] && this.childSpan[channel - 1].span) {
|
|
||||||
this.childSpan[channel - 1].span.setAttributes({
|
|
||||||
channel,
|
|
||||||
'stt.resolve': 'connection failure'
|
|
||||||
});
|
|
||||||
this.childSpan[channel - 1].span.end();
|
|
||||||
}
|
|
||||||
this.notifyTaskDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
_onJambonzConnect(_cs, _ep) {
|
|
||||||
this.logger.debug('TaskTranscribe:_onJambonzConnect');
|
|
||||||
}
|
|
||||||
|
|
||||||
_onJambonzConnectFailure(cs, _ep, evt) {
|
|
||||||
const {reason} = evt;
|
|
||||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
|
||||||
this.logger.info({evt}, 'TaskTranscribe:_onJambonzConnectFailure');
|
|
||||||
writeAlerts({
|
|
||||||
account_sid: cs.accountSid,
|
|
||||||
alert_type: AlertType.STT_FAILURE,
|
|
||||||
message: `Failed connecting to ${this.vendor} speech recognizer: ${reason}`,
|
|
||||||
vendor: this.vendor,
|
|
||||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for jambonz custom connection failure'));
|
|
||||||
this.notifyError({msg: 'ASR error', details:`Failed connecting to speech vendor ${this.vendor}: ${reason}`});
|
|
||||||
this.notifyTaskDone();
|
|
||||||
}
|
|
||||||
|
|
||||||
_onIbmConnect(_cs, _ep) {
|
|
||||||
this.logger.debug('TaskTranscribe:_onIbmConnect');
|
|
||||||
}
|
|
||||||
|
|
||||||
_onIbmConnectFailure(cs, _ep, channel, evt) {
|
|
||||||
const {reason} = evt;
|
|
||||||
const {writeAlerts, AlertType} = cs.srf.locals;
|
|
||||||
this.logger.info({evt}, 'TaskTranscribe:_onIbmConnectFailure');
|
|
||||||
writeAlerts({
|
|
||||||
account_sid: cs.accountSid,
|
|
||||||
alert_type: AlertType.STT_FAILURE,
|
|
||||||
message: `Failed connecting to IBM watson speech recognizer: ${reason}`,
|
|
||||||
vendor: 'ibm',
|
|
||||||
}).catch((err) => this.logger.info({err}, 'Error generating alert for IBM connection failure'));
|
|
||||||
this.notifyError(`Failed connecting to speech vendor IBM: ${reason}`);
|
|
||||||
|
|
||||||
if (this.childSpan[channel - 1] && this.childSpan[channel - 1].span) {
|
|
||||||
this.childSpan[channel - 1].span.setAttributes({
|
|
||||||
channel,
|
|
||||||
'stt.resolve': 'connection failure'
|
|
||||||
});
|
|
||||||
this.childSpan[channel - 1].span.end();
|
|
||||||
}
|
|
||||||
this.notifyTaskDone();
|
|
||||||
}
|
|
||||||
_onIbmError(cs, _ep, _channel, evt) {
|
|
||||||
this.logger.info({evt}, 'TaskTranscribe:_onIbmError');
|
|
||||||
}
|
|
||||||
async _onJambonzError(cs, _ep, evt) {
|
async _onJambonzError(cs, _ep, evt) {
|
||||||
this.logger.info({evt}, 'TaskTranscribe:_onJambonzError');
|
this.logger.info({evt}, 'TaskTranscribe:_onJambonzError');
|
||||||
if (this.isHandledByPrimaryProvider && this.fallbackVendor) {
|
if (this.isHandledByPrimaryProvider && this.fallbackVendor) {
|
||||||
@@ -589,6 +529,18 @@ class TaskTranscribe extends SttTask {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_onVendorConnectFailure(cs, _ep, channel, evt) {
|
||||||
|
super._onVendorConnectFailure(cs, _ep, evt);
|
||||||
|
if (this.childSpan[channel - 1] && this.childSpan[channel - 1].span) {
|
||||||
|
this.childSpan[channel - 1].span.setAttributes({
|
||||||
|
channel,
|
||||||
|
'stt.resolve': 'connection failure'
|
||||||
|
});
|
||||||
|
this.childSpan[channel - 1].span.end();
|
||||||
|
}
|
||||||
|
this.notifyTaskDone();
|
||||||
|
}
|
||||||
|
|
||||||
_startAsrTimer(channel) {
|
_startAsrTimer(channel) {
|
||||||
if (this.vendor === 'deepgram') return; // no need
|
if (this.vendor === 'deepgram') return; // no need
|
||||||
assert(this.isContinuousAsr);
|
assert(this.isContinuousAsr);
|
||||||
|
|||||||
@@ -126,6 +126,12 @@
|
|||||||
"Connect": "jambonz_transcribe::connect",
|
"Connect": "jambonz_transcribe::connect",
|
||||||
"Error": "jambonz_transcribe::error"
|
"Error": "jambonz_transcribe::error"
|
||||||
},
|
},
|
||||||
|
"AssemblyAiTranscriptionEvents": {
|
||||||
|
"Transcription": "assemblyai_transcribe::transcription",
|
||||||
|
"Error": "assemblyai_transcribe::error",
|
||||||
|
"ConnectFailure": "assemblyai_transcribe::connect_failed",
|
||||||
|
"Connect": "assemblyai_transcribe::connect"
|
||||||
|
},
|
||||||
"ListenEvents": {
|
"ListenEvents": {
|
||||||
"Connect": "mod_audio_fork::connect",
|
"Connect": "mod_audio_fork::connect",
|
||||||
"ConnectFailure": "mod_audio_fork::connect_failed",
|
"ConnectFailure": "mod_audio_fork::connect_failed",
|
||||||
|
|||||||
@@ -91,6 +91,9 @@ const speechMapper = (cred) => {
|
|||||||
const o = JSON.parse(decrypt(credential));
|
const o = JSON.parse(decrypt(credential));
|
||||||
obj.api_key = o.api_key;
|
obj.api_key = o.api_key;
|
||||||
obj.model_id = o.model_id;
|
obj.model_id = o.model_id;
|
||||||
|
} else if ('assemblyai' === obj.vendor) {
|
||||||
|
const o = JSON.parse(decrypt(credential));
|
||||||
|
obj.api_key = o.api_key;
|
||||||
} else if (obj.vendor.startsWith('custom:')) {
|
} else if (obj.vendor.startsWith('custom:')) {
|
||||||
const o = JSON.parse(decrypt(credential));
|
const o = JSON.parse(decrypt(credential));
|
||||||
obj.auth_token = o.auth_token;
|
obj.auth_token = o.auth_token;
|
||||||
|
|||||||
@@ -140,7 +140,8 @@ function installSrfLocals(srf, logger) {
|
|||||||
lookupTeamsByAccount,
|
lookupTeamsByAccount,
|
||||||
lookupAccountBySid,
|
lookupAccountBySid,
|
||||||
lookupAccountCapacitiesBySid,
|
lookupAccountCapacitiesBySid,
|
||||||
lookupSmppGateways
|
lookupSmppGateways,
|
||||||
|
lookupClientByAccountAndUsername
|
||||||
} = require('@jambonz/db-helpers')({
|
} = require('@jambonz/db-helpers')({
|
||||||
host: JAMBONES_MYSQL_HOST,
|
host: JAMBONES_MYSQL_HOST,
|
||||||
user: JAMBONES_MYSQL_USER,
|
user: JAMBONES_MYSQL_USER,
|
||||||
@@ -217,6 +218,7 @@ function installSrfLocals(srf, logger) {
|
|||||||
lookupAccountBySid,
|
lookupAccountBySid,
|
||||||
lookupAccountCapacitiesBySid,
|
lookupAccountCapacitiesBySid,
|
||||||
lookupSmppGateways,
|
lookupSmppGateways,
|
||||||
|
lookupClientByAccountAndUsername,
|
||||||
updateCallStatus,
|
updateCallStatus,
|
||||||
retrieveCall,
|
retrieveCall,
|
||||||
listCalls,
|
listCalls,
|
||||||
|
|||||||
@@ -334,6 +334,7 @@ class SingleDialer extends Emitter {
|
|||||||
// verify it contains only allowed verbs
|
// verify it contains only allowed verbs
|
||||||
const allowedTasks = tasks.filter((task) => {
|
const allowedTasks = tasks.filter((task) => {
|
||||||
return [
|
return [
|
||||||
|
TaskPreconditions.None,
|
||||||
TaskPreconditions.StableCall,
|
TaskPreconditions.StableCall,
|
||||||
TaskPreconditions.Endpoint
|
TaskPreconditions.Endpoint
|
||||||
].includes(task.preconditions);
|
].includes(task.preconditions);
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ const {
|
|||||||
SonioxTranscriptionEvents,
|
SonioxTranscriptionEvents,
|
||||||
NvidiaTranscriptionEvents,
|
NvidiaTranscriptionEvents,
|
||||||
CobaltTranscriptionEvents,
|
CobaltTranscriptionEvents,
|
||||||
JambonzTranscriptionEvents
|
JambonzTranscriptionEvents,
|
||||||
} = require('./constants');
|
AssemblyAiTranscriptionEvents
|
||||||
|
} = require('./constants.json');
|
||||||
|
|
||||||
const stickyVars = {
|
const stickyVars = {
|
||||||
google: [
|
google: [
|
||||||
@@ -104,6 +105,10 @@ const stickyVars = {
|
|||||||
soniox: [
|
soniox: [
|
||||||
'SONIOX_PROFANITY_FILTER',
|
'SONIOX_PROFANITY_FILTER',
|
||||||
'SONIOX_MODEL'
|
'SONIOX_MODEL'
|
||||||
|
],
|
||||||
|
assemblyai: [
|
||||||
|
'ASSEMBLYAI_API_KEY',
|
||||||
|
'ASSEMBLYAI_WORD_BOOST'
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -375,6 +380,24 @@ const normalizeAws = (evt, channel, language) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const normalizeAssemblyAi = (evt, channel, language) => {
|
||||||
|
const copy = JSON.parse(JSON.stringify(evt));
|
||||||
|
return {
|
||||||
|
language_code: language,
|
||||||
|
channel_tag: channel,
|
||||||
|
is_final: evt.message_type === 'FinalTranscript',
|
||||||
|
alternatives: [
|
||||||
|
{
|
||||||
|
confidence: evt.confidence,
|
||||||
|
transcript: evt.text,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
vendor: {
|
||||||
|
name: 'ASSEMBLYAI',
|
||||||
|
evt: copy
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = (logger) => {
|
module.exports = (logger) => {
|
||||||
const normalizeTranscription = (evt, vendor, channel, language, shortUtterance) => {
|
const normalizeTranscription = (evt, vendor, channel, language, shortUtterance) => {
|
||||||
@@ -399,6 +422,8 @@ module.exports = (logger) => {
|
|||||||
return normalizeSoniox(evt, channel, language);
|
return normalizeSoniox(evt, channel, language);
|
||||||
case 'cobalt':
|
case 'cobalt':
|
||||||
return normalizeCobalt(evt, channel, language);
|
return normalizeCobalt(evt, channel, language);
|
||||||
|
case 'assemblyai':
|
||||||
|
return normalizeAssemblyAi(evt, channel, language, shortUtterance);
|
||||||
default:
|
default:
|
||||||
if (vendor.startsWith('custom:')) {
|
if (vendor.startsWith('custom:')) {
|
||||||
return normalizeCustom(evt, channel, language, vendor);
|
return normalizeCustom(evt, channel, language, vendor);
|
||||||
@@ -692,6 +717,14 @@ module.exports = (logger) => {
|
|||||||
...(cobaltOptions.enableConfusionNetwork && {COBALT_ENABLE_CONFUSION_NETWORK: 1}),
|
...(cobaltOptions.enableConfusionNetwork && {COBALT_ENABLE_CONFUSION_NETWORK: 1}),
|
||||||
...(cobaltOptions.compiledContextData && {COBALT_COMPILED_CONTEXT_DATA: cobaltOptions.compiledContextData}),
|
...(cobaltOptions.compiledContextData && {COBALT_COMPILED_CONTEXT_DATA: cobaltOptions.compiledContextData}),
|
||||||
};
|
};
|
||||||
|
} else if ('assemblyai' === vendor) {
|
||||||
|
opts = {
|
||||||
|
...opts,
|
||||||
|
...(sttCredentials.api_key) &&
|
||||||
|
{ASSEMBLYAI_API_KEY: sttCredentials.api_key},
|
||||||
|
...(rOpts.hints?.length > 0 &&
|
||||||
|
{ASSEMBLYAI_WORD_BOOST: JSON.stringify(rOpts.hints)})
|
||||||
|
};
|
||||||
}
|
}
|
||||||
else if (vendor.startsWith('custom:')) {
|
else if (vendor.startsWith('custom:')) {
|
||||||
let {options = {}} = rOpts;
|
let {options = {}} = rOpts;
|
||||||
@@ -755,6 +788,10 @@ module.exports = (logger) => {
|
|||||||
ep.removeCustomEventListener(JambonzTranscriptionEvents.ConnectFailure);
|
ep.removeCustomEventListener(JambonzTranscriptionEvents.ConnectFailure);
|
||||||
|
|
||||||
ep.removeCustomEventListener(JambonzTranscriptionEvents.Error);
|
ep.removeCustomEventListener(JambonzTranscriptionEvents.Error);
|
||||||
|
|
||||||
|
ep.removeCustomEventListener(AssemblyAiTranscriptionEvents.Transcription);
|
||||||
|
ep.removeCustomEventListener(AssemblyAiTranscriptionEvents.Connect);
|
||||||
|
ep.removeCustomEventListener(AssemblyAiTranscriptionEvents.ConnectFailure);
|
||||||
};
|
};
|
||||||
|
|
||||||
const setSpeechCredentialsAtRuntime = (recognizer) => {
|
const setSpeechCredentialsAtRuntime = (recognizer) => {
|
||||||
|
|||||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -18,7 +18,7 @@
|
|||||||
"@jambonz/speech-utils": "^0.0.24",
|
"@jambonz/speech-utils": "^0.0.24",
|
||||||
"@jambonz/stats-collector": "^0.1.9",
|
"@jambonz/stats-collector": "^0.1.9",
|
||||||
"@jambonz/time-series": "^0.2.8",
|
"@jambonz/time-series": "^0.2.8",
|
||||||
"@jambonz/verb-specifications": "^0.0.44",
|
"@jambonz/verb-specifications": "^0.0.45",
|
||||||
"@opentelemetry/api": "^1.4.0",
|
"@opentelemetry/api": "^1.4.0",
|
||||||
"@opentelemetry/exporter-jaeger": "^1.9.0",
|
"@opentelemetry/exporter-jaeger": "^1.9.0",
|
||||||
"@opentelemetry/exporter-trace-otlp-http": "^0.35.0",
|
"@opentelemetry/exporter-trace-otlp-http": "^0.35.0",
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"deepcopy": "^2.1.0",
|
"deepcopy": "^2.1.0",
|
||||||
"drachtio-fsmrf": "^3.0.27",
|
"drachtio-fsmrf": "^3.0.27",
|
||||||
"drachtio-srf": "^4.5.29",
|
"drachtio-srf": "^4.5.31",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-validator": "^7.0.1",
|
"express-validator": "^7.0.1",
|
||||||
"ip": "^1.1.8",
|
"ip": "^1.1.8",
|
||||||
@@ -3181,9 +3181,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jambonz/verb-specifications": {
|
"node_modules/@jambonz/verb-specifications": {
|
||||||
"version": "0.0.44",
|
"version": "0.0.45",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.44.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.45.tgz",
|
||||||
"integrity": "sha512-mXTbZlJ3AprxooSNvEHYt/9wsky4wHT4mJmL2XrkZGQY6fG/LzVNFVy0Tvx0xZzAVJMY9SmNcDiM0HBNnAufIg==",
|
"integrity": "sha512-0cC7cfyXuOlqjfrtA9GC7A84efInj4z+ZSsibONqHMw3FVJE5IvcvabRojarDHooIn9Uw6AEX/zZ7BZqfgVmJw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"pino": "^8.8.0"
|
"pino": "^8.8.0"
|
||||||
@@ -5360,9 +5360,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/drachtio-srf": {
|
"node_modules/drachtio-srf": {
|
||||||
"version": "4.5.29",
|
"version": "4.5.31",
|
||||||
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.5.29.tgz",
|
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.5.31.tgz",
|
||||||
"integrity": "sha512-Hj2OW+SyQxAyLpyHngJwW26FX9V4fDYZGX0mlU4YOF4ml7I7b7XITcRPxKhroYDOrLgKqhNeh5BcPoKqPhEK7A==",
|
"integrity": "sha512-/M4J8h2aqHtMXWr8/UHngKQsY9sQQxjdd23jDTSpNVpCwgZ2/xZFhbg/B/UCjrarSRzbyDCvuluOAtaPRSw7Hw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": "^3.2.7",
|
"debug": "^3.2.7",
|
||||||
"delegates": "^0.1.0",
|
"delegates": "^0.1.0",
|
||||||
@@ -13275,9 +13275,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@jambonz/verb-specifications": {
|
"@jambonz/verb-specifications": {
|
||||||
"version": "0.0.44",
|
"version": "0.0.45",
|
||||||
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.44.tgz",
|
"resolved": "https://registry.npmjs.org/@jambonz/verb-specifications/-/verb-specifications-0.0.45.tgz",
|
||||||
"integrity": "sha512-mXTbZlJ3AprxooSNvEHYt/9wsky4wHT4mJmL2XrkZGQY6fG/LzVNFVy0Tvx0xZzAVJMY9SmNcDiM0HBNnAufIg==",
|
"integrity": "sha512-0cC7cfyXuOlqjfrtA9GC7A84efInj4z+ZSsibONqHMw3FVJE5IvcvabRojarDHooIn9Uw6AEX/zZ7BZqfgVmJw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"pino": "^8.8.0"
|
"pino": "^8.8.0"
|
||||||
@@ -14944,9 +14944,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"drachtio-srf": {
|
"drachtio-srf": {
|
||||||
"version": "4.5.29",
|
"version": "4.5.31",
|
||||||
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.5.29.tgz",
|
"resolved": "https://registry.npmjs.org/drachtio-srf/-/drachtio-srf-4.5.31.tgz",
|
||||||
"integrity": "sha512-Hj2OW+SyQxAyLpyHngJwW26FX9V4fDYZGX0mlU4YOF4ml7I7b7XITcRPxKhroYDOrLgKqhNeh5BcPoKqPhEK7A==",
|
"integrity": "sha512-/M4J8h2aqHtMXWr8/UHngKQsY9sQQxjdd23jDTSpNVpCwgZ2/xZFhbg/B/UCjrarSRzbyDCvuluOAtaPRSw7Hw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^3.2.7",
|
"debug": "^3.2.7",
|
||||||
"delegates": "^0.1.0",
|
"delegates": "^0.1.0",
|
||||||
|
|||||||
@@ -34,7 +34,7 @@
|
|||||||
"@jambonz/speech-utils": "^0.0.24",
|
"@jambonz/speech-utils": "^0.0.24",
|
||||||
"@jambonz/stats-collector": "^0.1.9",
|
"@jambonz/stats-collector": "^0.1.9",
|
||||||
"@jambonz/time-series": "^0.2.8",
|
"@jambonz/time-series": "^0.2.8",
|
||||||
"@jambonz/verb-specifications": "^0.0.44",
|
"@jambonz/verb-specifications": "^0.0.45",
|
||||||
"@opentelemetry/api": "^1.4.0",
|
"@opentelemetry/api": "^1.4.0",
|
||||||
"@opentelemetry/exporter-jaeger": "^1.9.0",
|
"@opentelemetry/exporter-jaeger": "^1.9.0",
|
||||||
"@opentelemetry/exporter-trace-otlp-http": "^0.35.0",
|
"@opentelemetry/exporter-trace-otlp-http": "^0.35.0",
|
||||||
@@ -48,7 +48,7 @@
|
|||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"deepcopy": "^2.1.0",
|
"deepcopy": "^2.1.0",
|
||||||
"drachtio-fsmrf": "^3.0.27",
|
"drachtio-fsmrf": "^3.0.27",
|
||||||
"drachtio-srf": "^4.5.29",
|
"drachtio-srf": "^4.5.31",
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"express-validator": "^7.0.1",
|
"express-validator": "^7.0.1",
|
||||||
"ip": "^1.1.8",
|
"ip": "^1.1.8",
|
||||||
|
|||||||
Reference in New Issue
Block a user