@webex/internal-plugin-voicea 2.25.0 → 2.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/voicea.js +61 -47
- package/dist/voicea.js.map +1 -1
- package/dist/voicea.types.js.map +1 -1
- package/package.json +3 -4
- package/src/constants.ts +2 -1
- package/src/index.ts +2 -1
- package/src/voicea.ts +43 -31
- package/src/voicea.types.ts +1 -0
- package/test/unit/spec/voicea.js +67 -50
package/dist/constants.js
CHANGED
|
@@ -6,7 +6,7 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
8
|
|
|
9
|
-
exports.VOICEA_RELAY_TYPES = exports.TRANSCRIPTION_TYPE = exports.EVENT_TRIGGERS = void 0;
|
|
9
|
+
exports.VOICEA_RELAY_TYPES = exports.VOICEA = exports.TRANSCRIPTION_TYPE = exports.EVENT_TRIGGERS = void 0;
|
|
10
10
|
var EVENT_TRIGGERS = {
|
|
11
11
|
VOICEA_ANNOUNCEMENT: 'voicea:announcement',
|
|
12
12
|
CAPTION_LANGUAGE_UPDATE: 'voicea:captionLanguageUpdate',
|
|
@@ -37,4 +37,6 @@ var TRANSCRIPTION_TYPE = {
|
|
|
37
37
|
TRANSCRIPT_FINAL_RESULT: 'transcript_final_result'
|
|
38
38
|
};
|
|
39
39
|
exports.TRANSCRIPTION_TYPE = TRANSCRIPTION_TYPE;
|
|
40
|
+
var VOICEA = 'voicea';
|
|
41
|
+
exports.VOICEA = VOICEA;
|
|
40
42
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["EVENT_TRIGGERS","VOICEA_ANNOUNCEMENT","CAPTION_LANGUAGE_UPDATE","SPOKEN_LANGUAGE_UPDATE","CAPTIONS_TURNED_ON","TRANSCRIBING_ON","TRANSCRIBING_OFF","NEW_CAPTION","EVA_COMMAND","HIGHLIGHT_CREATED","VOICEA_RELAY_TYPES","ANNOUNCEMENT","CLIENT_ANNOUNCEMENT","TRANSLATION_REQUEST","TRANSLATION_RESPONSE","TRANSCRIPTION","TRANSCRIPTION_TYPE","UNKNOWN","EVA_WAKE","EVA_THANKS","EVA_CANCEL","TRANSCRIPT_INTERIM_RESULTS","TRANSCRIPT_FINAL_RESULT"],"sources":["constants.ts"],"sourcesContent":["export const EVENT_TRIGGERS = {\n VOICEA_ANNOUNCEMENT: 'voicea:announcement',\n CAPTION_LANGUAGE_UPDATE: 'voicea:captionLanguageUpdate',\n SPOKEN_LANGUAGE_UPDATE: 'voicea:spokenLanguageUpdate',\n CAPTIONS_TURNED_ON: 'voicea:captionOn',\n TRANSCRIBING_ON: 'voicea:transcribingOn',\n TRANSCRIBING_OFF: 'voicea:transcribingOff',\n\n NEW_CAPTION: 'voicea:newCaption',\n EVA_COMMAND: 'voicea:wxa',\n HIGHLIGHT_CREATED: 'voicea:highlightCreated'\n};\n\nexport const VOICEA_RELAY_TYPES = {\n ANNOUNCEMENT: 'voicea.annc',\n CLIENT_ANNOUNCEMENT: 'client.annc',\n TRANSLATION_REQUEST: 'voicea.transl.req',\n TRANSLATION_RESPONSE: 'voicea.transl.rsp',\n TRANSCRIPTION: 'voicea.transcription'\n};\n\nexport const TRANSCRIPTION_TYPE = {\n UNKNOWN: 'unknown',\n EVA_WAKE: 'eva_wake',\n EVA_THANKS: 'eva_thanks',\n EVA_CANCEL: 'eva_cancel',\n HIGHLIGHT_CREATED: 'highlight_created',\n TRANSCRIPT_INTERIM_RESULTS: 'transcript_interim_results',\n TRANSCRIPT_FINAL_RESULT: 'transcript_final_result'\n
|
|
1
|
+
{"version":3,"names":["EVENT_TRIGGERS","VOICEA_ANNOUNCEMENT","CAPTION_LANGUAGE_UPDATE","SPOKEN_LANGUAGE_UPDATE","CAPTIONS_TURNED_ON","TRANSCRIBING_ON","TRANSCRIBING_OFF","NEW_CAPTION","EVA_COMMAND","HIGHLIGHT_CREATED","VOICEA_RELAY_TYPES","ANNOUNCEMENT","CLIENT_ANNOUNCEMENT","TRANSLATION_REQUEST","TRANSLATION_RESPONSE","TRANSCRIPTION","TRANSCRIPTION_TYPE","UNKNOWN","EVA_WAKE","EVA_THANKS","EVA_CANCEL","TRANSCRIPT_INTERIM_RESULTS","TRANSCRIPT_FINAL_RESULT","VOICEA"],"sources":["constants.ts"],"sourcesContent":["export const EVENT_TRIGGERS = {\n VOICEA_ANNOUNCEMENT: 'voicea:announcement',\n CAPTION_LANGUAGE_UPDATE: 'voicea:captionLanguageUpdate',\n SPOKEN_LANGUAGE_UPDATE: 'voicea:spokenLanguageUpdate',\n CAPTIONS_TURNED_ON: 'voicea:captionOn',\n TRANSCRIBING_ON: 'voicea:transcribingOn',\n TRANSCRIBING_OFF: 'voicea:transcribingOff',\n\n NEW_CAPTION: 'voicea:newCaption',\n EVA_COMMAND: 'voicea:wxa',\n HIGHLIGHT_CREATED: 'voicea:highlightCreated'\n};\n\nexport const VOICEA_RELAY_TYPES = {\n ANNOUNCEMENT: 'voicea.annc',\n CLIENT_ANNOUNCEMENT: 'client.annc',\n TRANSLATION_REQUEST: 'voicea.transl.req',\n TRANSLATION_RESPONSE: 'voicea.transl.rsp',\n TRANSCRIPTION: 'voicea.transcription'\n};\n\nexport const TRANSCRIPTION_TYPE = {\n UNKNOWN: 'unknown',\n EVA_WAKE: 'eva_wake',\n EVA_THANKS: 'eva_thanks',\n EVA_CANCEL: 'eva_cancel',\n HIGHLIGHT_CREATED: 'highlight_created',\n TRANSCRIPT_INTERIM_RESULTS: 'transcript_interim_results',\n TRANSCRIPT_FINAL_RESULT: 'transcript_final_result'\n};\n\nexport const VOICEA = 'voicea';\n"],"mappings":";;;;;;;;;AAAO,IAAMA,cAAc,GAAG;EAC5BC,mBAAmB,EAAE,qBADO;EAE5BC,uBAAuB,EAAE,8BAFG;EAG5BC,sBAAsB,EAAE,6BAHI;EAI5BC,kBAAkB,EAAE,kBAJQ;EAK5BC,eAAe,EAAE,uBALW;EAM5BC,gBAAgB,EAAE,wBANU;EAQ5BC,WAAW,EAAE,mBARe;EAS5BC,WAAW,EAAE,YATe;EAU5BC,iBAAiB,EAAE;AAVS,CAAvB;;AAaA,IAAMC,kBAAkB,GAAG;EAChCC,YAAY,EAAE,aADkB;EAEhCC,mBAAmB,EAAE,aAFW;EAGhCC,mBAAmB,EAAE,mBAHW;EAIhCC,oBAAoB,EAAE,mBAJU;EAKhCC,aAAa,EAAE;AALiB,CAA3B;;AAQA,IAAMC,kBAAkB,GAAG;EAChCC,OAAO,EAAE,SADuB;EAEhCC,QAAQ,EAAE,UAFsB;EAGhCC,UAAU,EAAE,YAHoB;EAIhCC,UAAU,EAAE,YAJoB;EAKhCX,iBAAiB,EAAE,mBALa;EAMhCY,0BAA0B,EAAE,4BANI;EAOhCC,uBAAuB,EAAE;AAPO,CAA3B;;AAUA,IAAMC,MAAM,GAAG,QAAf"}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["WebexCore","registerInternalPlugin","VoiceaChannel"],"sources":["index.ts"],"sourcesContent":["import * as WebexCore from '@webex/webex-core';\nimport VoiceaChannel from './voicea';\n\nWebexCore.registerInternalPlugin('voicea', VoiceaChannel, {});\n\nexport {default} from './voicea'
|
|
1
|
+
{"version":3,"names":["WebexCore","registerInternalPlugin","VoiceaChannel"],"sources":["index.ts"],"sourcesContent":["import * as WebexCore from '@webex/webex-core';\n\nimport VoiceaChannel from './voicea';\n\nWebexCore.registerInternalPlugin('voicea', VoiceaChannel, {});\n\nexport {default} from './voicea';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;;AAEA;;;;;;AAEAA,SAAS,CAACC,sBAAV,CAAiC,QAAjC,EAA2CC,eAA3C,EAA0D,EAA1D"}
|
package/dist/voicea.js
CHANGED
|
@@ -16,10 +16,10 @@ var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regene
|
|
|
16
16
|
|
|
17
17
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
18
18
|
|
|
19
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
20
|
-
|
|
21
19
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
22
20
|
|
|
21
|
+
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
22
|
+
|
|
23
23
|
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/assertThisInitialized"));
|
|
24
24
|
|
|
25
25
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
@@ -32,8 +32,6 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/he
|
|
|
32
32
|
|
|
33
33
|
var _uuid = _interopRequireDefault(require("uuid"));
|
|
34
34
|
|
|
35
|
-
var _internalPluginLlm = _interopRequireDefault(require("@webex/internal-plugin-llm"));
|
|
36
|
-
|
|
37
35
|
var _pluginMeetings = require("@webex/plugin-meetings");
|
|
38
36
|
|
|
39
37
|
var _webexCore = require("@webex/webex-core");
|
|
@@ -49,8 +47,8 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_R
|
|
|
49
47
|
/**
|
|
50
48
|
* VoiceaChannel to hold single instance of LLM
|
|
51
49
|
*/
|
|
52
|
-
var VoiceaChannel = /*#__PURE__*/function (
|
|
53
|
-
(0, _inherits2.default)(VoiceaChannel,
|
|
50
|
+
var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
51
|
+
(0, _inherits2.default)(VoiceaChannel, _WebexPlugin);
|
|
54
52
|
|
|
55
53
|
var _super = _createSuper(VoiceaChannel);
|
|
56
54
|
|
|
@@ -68,6 +66,7 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
68
66
|
}
|
|
69
67
|
|
|
70
68
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
69
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "namespace", _constants.VOICEA);
|
|
71
70
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "seqNum", void 0);
|
|
72
71
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "hasVoiceaJoined", void 0);
|
|
73
72
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "areCaptionsEnabled", void 0);
|
|
@@ -84,8 +83,9 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
84
83
|
transcriptId: voiceaPayload.transcript_id,
|
|
85
84
|
translations: voiceaPayload.translations,
|
|
86
85
|
transcript: {
|
|
87
|
-
csis: voiceaPayload.csis,
|
|
88
|
-
text: voiceaPayload.data
|
|
86
|
+
csis: voiceaPayload.transcripts[0] ? voiceaPayload.transcripts[0].csis : [],
|
|
87
|
+
text: voiceaPayload.data,
|
|
88
|
+
transcriptLanguageCode: voiceaPayload.transcripts[0].transcript_language_code
|
|
89
89
|
}
|
|
90
90
|
});
|
|
91
91
|
|
|
@@ -101,9 +101,10 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
101
101
|
translations: voiceaPayload.translations,
|
|
102
102
|
transcript: {
|
|
103
103
|
csis: voiceaPayload.csis,
|
|
104
|
-
text: voiceaPayload.
|
|
104
|
+
text: voiceaPayload.transcript.text,
|
|
105
|
+
transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code
|
|
105
106
|
},
|
|
106
|
-
timestamp: (0, _utils.millisToMinutesAndSeconds)(voiceaPayload.transcript.end_millis
|
|
107
|
+
timestamp: (0, _utils.millisToMinutesAndSeconds)(voiceaPayload.transcript.end_millis)
|
|
107
108
|
});
|
|
108
109
|
|
|
109
110
|
break;
|
|
@@ -118,7 +119,7 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
118
119
|
text: voiceaPayload.highlight.transcript,
|
|
119
120
|
highlightLabel: voiceaPayload.highlight.highlight_label,
|
|
120
121
|
highlightSource: voiceaPayload.highlight.highlight_source,
|
|
121
|
-
timestamp: (0, _utils.millisToMinutesAndSeconds)(voiceaPayload.highlight.end_millis
|
|
122
|
+
timestamp: (0, _utils.millisToMinutesAndSeconds)(voiceaPayload.highlight.end_millis)
|
|
122
123
|
});
|
|
123
124
|
|
|
124
125
|
break;
|
|
@@ -182,13 +183,15 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
182
183
|
}, _constants.EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, voiceaLanguageOptions);
|
|
183
184
|
});
|
|
184
185
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sendAnnouncement", function () {
|
|
185
|
-
if (_this.hasVoiceaJoined) return;
|
|
186
|
+
if (_this.hasVoiceaJoined || !_this.webex.internal.llm.isConnected()) return;
|
|
187
|
+
|
|
188
|
+
_this.listenToEvents();
|
|
186
189
|
|
|
187
|
-
_this.socket.send({
|
|
190
|
+
_this.webex.internal.llm.socket.send({
|
|
188
191
|
id: "".concat(_this.seqNum),
|
|
189
192
|
type: 'publishRequest',
|
|
190
193
|
recipients: {
|
|
191
|
-
route: _this.getBinding()
|
|
194
|
+
route: _this.webex.internal.llm.getBinding()
|
|
192
195
|
},
|
|
193
196
|
headers: {},
|
|
194
197
|
data: {
|
|
@@ -206,7 +209,7 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
206
209
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setSpokenLanguage", function (languageCode) {
|
|
207
210
|
return _this.request({
|
|
208
211
|
method: 'PUT',
|
|
209
|
-
url: "".concat(_this.getLocusUrl(), "/controls/"),
|
|
212
|
+
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
210
213
|
body: {
|
|
211
214
|
languageCode: languageCode
|
|
212
215
|
}
|
|
@@ -220,11 +223,13 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
220
223
|
});
|
|
221
224
|
});
|
|
222
225
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "requestLanguage", function (languageCode) {
|
|
223
|
-
_this.
|
|
226
|
+
if (!_this.webex.internal.llm.isConnected()) return;
|
|
227
|
+
|
|
228
|
+
_this.webex.internal.llm.socket.send({
|
|
224
229
|
id: "".concat(_this.seqNum),
|
|
225
230
|
type: 'publishRequest',
|
|
226
231
|
recipients: {
|
|
227
|
-
route: _this.getBinding()
|
|
232
|
+
route: _this.webex.internal.llm.getBinding()
|
|
228
233
|
},
|
|
229
234
|
headers: {
|
|
230
235
|
to: _this.vmcDeviceId
|
|
@@ -257,7 +262,7 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
257
262
|
case 2:
|
|
258
263
|
return _context.abrupt("return", _this.request({
|
|
259
264
|
method: 'PUT',
|
|
260
|
-
url: "".concat(_this.getLocusUrl(), "/controls/"),
|
|
265
|
+
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
261
266
|
body: {
|
|
262
267
|
transcribe: {
|
|
263
268
|
caption: true
|
|
@@ -297,7 +302,7 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
297
302
|
case 2:
|
|
298
303
|
return _context2.abrupt("return", _this.request({
|
|
299
304
|
method: 'PUT',
|
|
300
|
-
url: "".concat(_this.getLocusUrl(), "/controls/"),
|
|
305
|
+
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
301
306
|
body: {
|
|
302
307
|
transcribe: {
|
|
303
308
|
transcribing: activate
|
|
@@ -330,45 +335,54 @@ var VoiceaChannel = /*#__PURE__*/function (_LLMChannel) {
|
|
|
330
335
|
_this.areCaptionsEnabled = false;
|
|
331
336
|
_this.isTranscribingEnabled = false;
|
|
332
337
|
_this.vmcDeviceId = undefined;
|
|
338
|
+
return _this;
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Process Transcript and send alert
|
|
342
|
+
* @param {TranscriptionResponse} voiceaPayload
|
|
343
|
+
* @returns {void}
|
|
344
|
+
*/
|
|
333
345
|
|
|
334
|
-
_this.on('event:relay.event', function (e) {
|
|
335
|
-
_this.seqNum = e.sequenceNumber + 1;
|
|
336
346
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
347
|
+
(0, _createClass2.default)(VoiceaChannel, [{
|
|
348
|
+
key: "listenToEvents",
|
|
349
|
+
value:
|
|
350
|
+
/**
|
|
351
|
+
* Listen to websocket messages
|
|
352
|
+
*/
|
|
353
|
+
function listenToEvents() {
|
|
354
|
+
var _this2 = this;
|
|
341
355
|
|
|
342
|
-
|
|
356
|
+
this.webex.internal.llm.on('event:relay.event', function (e) {
|
|
357
|
+
_this2.seqNum = e.sequenceNumber + 1;
|
|
343
358
|
|
|
344
|
-
|
|
359
|
+
switch (e.data.relayType) {
|
|
360
|
+
case _constants.VOICEA_RELAY_TYPES.ANNOUNCEMENT:
|
|
361
|
+
_this2.vmcDeviceId = e.headers.from;
|
|
362
|
+
_this2.hasVoiceaJoined = true;
|
|
345
363
|
|
|
346
|
-
|
|
347
|
-
_this.processCaptionLanguageResponse(e.voiceaPayload);
|
|
364
|
+
_this2.processAnnouncementMessage(e.data.voiceaPayload);
|
|
348
365
|
|
|
349
|
-
|
|
366
|
+
break;
|
|
350
367
|
|
|
351
|
-
|
|
352
|
-
|
|
368
|
+
case _constants.VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:
|
|
369
|
+
_this2.processCaptionLanguageResponse(e.data.voiceaPayload);
|
|
353
370
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
default:
|
|
357
|
-
break;
|
|
358
|
-
}
|
|
359
|
-
});
|
|
371
|
+
break;
|
|
360
372
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
* Process Transcript and send alert
|
|
365
|
-
* @param {TranscriptionResponse} voiceaPayload
|
|
366
|
-
* @returns {void}
|
|
367
|
-
*/
|
|
373
|
+
case _constants.VOICEA_RELAY_TYPES.TRANSCRIPTION:
|
|
374
|
+
_this2.processTranscription(e.data.voiceaPayload);
|
|
368
375
|
|
|
376
|
+
break;
|
|
369
377
|
|
|
370
|
-
|
|
371
|
-
|
|
378
|
+
default:
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
}]);
|
|
384
|
+
return VoiceaChannel;
|
|
385
|
+
}(_webexCore.WebexPlugin);
|
|
372
386
|
|
|
373
387
|
exports.VoiceaChannel = VoiceaChannel;
|
|
374
388
|
var _default = VoiceaChannel;
|
package/dist/voicea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["VoiceaChannel","args","voiceaPayload","type","TRANSCRIPTION_TYPE","TRANSCRIPT_INTERIM_RESULTS","Trigger","trigger","file","function","EVENT_TRIGGERS","NEW_CAPTION","isFinal","transcriptId","transcript_id","translations","transcript","csis","text","data","TRANSCRIPT_FINAL_RESULT","timestamp","millisToMinutesAndSeconds","end_millis","start_millis","HIGHLIGHT_CREATED","highlight","highlightId","highlight_id","highlightLabel","highlight_label","highlightSource","highlight_source","EVA_THANKS","EVA_COMMAND","isListening","command_response","EVA_WAKE","EVA_CANCEL","statusCode","CAPTION_LANGUAGE_UPDATE","errorCode","errorMessage","message","voiceaLanguageOptions","captionLanguages","translation","allowed_languages","maxLanguages","max_languages","spokenLanguages","ASR","spoken_languages","VOICEA_ANNOUNCEMENT","hasVoiceaJoined","socket","send","id","seqNum","recipients","route","getBinding","headers","clientPayload","version","eventType","relayType","VOICEA_RELAY_TYPES","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","languageCode","request","method","url","getLocusUrl","body","then","SPOKEN_LANGUAGE_UPDATE","to","vmcDeviceId","translationLanguage","TRANSLATION_REQUEST","areCaptionsEnabled","undefined","transcribe","caption","CAPTIONS_TURNED_ON","sendAnnouncement","activate","isTranscribingEnabled","transcribing","TRANSCRIBING_ON","TRANSCRIBING_OFF","turnOnCaptions","on","e","sequenceNumber","ANNOUNCEMENT","from","processAnnouncementMessage","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","LLMChannel"],"sources":["voicea.ts"],"sourcesContent":["import uuid from 'uuid';\nimport LLMChannel from '@webex/internal-plugin-llm';\nimport {TriggerProxy as Trigger} from '@webex/plugin-meetings';\nimport {config} from '@webex/webex-core';\n\nimport {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, IVoiceaChannel} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n/**\n * VoiceaChannel to hold single instance of LLM\n */\nexport class VoiceaChannel extends LLMChannel implements IVoiceaChannel {\n private seqNum: number;\n\n private hasVoiceaJoined: boolean;\n\n private areCaptionsEnabled: boolean;\n\n private isTranscribingEnabled:boolean;\n\n private vmcDeviceId: string;\n\n /**\n * Initializes Voicea plugin\n * @param {any} args\n */\n constructor(...args) {\n super(...args);\n this.seqNum = 1;\n this.hasVoiceaJoined = false;\n this.areCaptionsEnabled = false;\n this.isTranscribingEnabled = false;\n this.vmcDeviceId = undefined;\n\n this.on('event:relay.event', (e) => {\n this.seqNum = e.sequenceNumber + 1;\n switch (e.data.relayType) {\n case VOICEA_RELAY_TYPES.ANNOUNCEMENT:\n this.vmcDeviceId = e.headers.from;\n this.hasVoiceaJoined = true;\n this.processAnnouncementMessage(e.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:\n this.processCaptionLanguageResponse(e.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSCRIPTION:\n this.processTranscription(e.voiceaPayload);\n break;\n default:\n break;\n }\n });\n }\n\n /**\n * Process Transcript and send alert\n * @param {TranscriptionResponse} voiceaPayload\n * @returns {void}\n */\n private processTranscription = (voiceaPayload: TranscriptionResponse): void => {\n switch (voiceaPayload.type) {\n case TRANSCRIPTION_TYPE.TRANSCRIPT_INTERIM_RESULTS:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n translations: voiceaPayload.translations,\n transcript: {\n csis: voiceaPayload.csis,\n text: voiceaPayload.data\n },\n });\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\n translations: voiceaPayload.translations,\n transcript: {\n csis: voiceaPayload.csis,\n text: voiceaPayload.data\n },\n timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis - voiceaPayload.transcript.start_millis)\n });\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.HIGHLIGHT_CREATED, {\n csis: voiceaPayload.highlight.csis,\n highlightId: voiceaPayload.highlight.highlight_id,\n text: voiceaPayload.highlight.transcript,\n highlightLabel: voiceaPayload.highlight.highlight_label,\n highlightSource: voiceaPayload.highlight.highlight_source,\n timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis - voiceaPayload.highlight.start_millis)\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: false, text: voiceaPayload.command_response\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE\n });\n break;\n\n default:\n break;\n }\n };\n\n /**\n * Processes Caption Language Response\n * @param {CaptionLanguageResponse} voiceaPayload\n * @returns {void}\n */\n private processCaptionLanguageResponse = (voiceaPayload: CaptionLanguageResponse):void => {\n if (voiceaPayload.statusCode === 200) {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processCaptionLanguageResponse'\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: 200});\n }\n else {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processCaptionLanguageResponse'\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message});\n }\n };\n\n /**\n * processes voicea announcement response and triggers event\n * @param {Object} voiceaPayload\n * @returns {void}\n */\n private processAnnouncementMessage = (voiceaPayload: AnnouncementPayload):void => {\n const voiceaLanguageOptions = {\n captionLanguages: voiceaPayload?.translation?.allowed_languages ?? [],\n maxLanguages: voiceaPayload?.translation?.max_languages ?? 0,\n spokenLanguages: voiceaPayload?.ASR?.spoken_languages ?? [],\n };\n\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processAnnouncementMessage'\n },\n EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT,\n voiceaLanguageOptions\n );\n };\n\n\n /**\n * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n private sendAnnouncement = ():void => {\n if (this.hasVoiceaJoined) return;\n this.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.getBinding(),\n },\n headers: {},\n data: {\n clientPayload: {\n version: 'v2',\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.CLIENT_ANNOUNCEMENT,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`\n });\n this.seqNum += 1;\n };\n\n /**\n * Set Spoken Language for the meeting\n * @param {string} languageCode\n * @returns {Promise}\n */\n public setSpokenLanguage = (languageCode: string):Promise<void> => this.request({\n method: 'PUT',\n url: `${this.getLocusUrl()}/controls/`,\n body: {\n languageCode\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'setSpokenLanguage'\n },\n EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,\n {languageCode});\n });\n\n /**\n * Request Language translation\n * @param {string} languageCode\n * @returns {void}\n */\n public requestLanguage = (languageCode: string): void => {\n this.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.getBinding(),\n },\n headers: {\n to: this.vmcDeviceId,\n },\n data: {\n clientPayload: {\n translationLanguage: languageCode,\n id: uuid.v4(),\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.TRANSLATION_REQUEST,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`\n });\n this.seqNum += 1;\n };\n\n /**\n * Turn on Captions\n * @returns {Promise}\n */\n public turnOnCaptions = async (): undefined | Promise<void> => {\n if (this.hasVoiceaJoined && this.areCaptionsEnabled) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.getLocusUrl()}/controls/`,\n body: {\n transcribe: {caption: true}\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'turnOnCaptions'\n },\n EVENT_TRIGGERS.CAPTIONS_TURNED_ON);\n this.areCaptionsEnabled = true;\n this.sendAnnouncement();\n });\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {bool} activate if true transcribing is turned on\n * @returns {Promise}\n */\n public toggleTranscribing = async (activate:boolean):undefined|Promise<void> => {\n if (this.isTranscribingEnabled === activate) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.getLocusUrl()}/controls/`,\n body: {\n transcribe: {transcribing: activate}\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'toggleTranscribing'\n },\n activate ? EVENT_TRIGGERS.TRANSCRIBING_ON : EVENT_TRIGGERS.TRANSCRIBING_OFF);\n this.isTranscribingEnabled = activate;\n if (activate && !this.areCaptionsEnabled && !this.hasVoiceaJoined) this.turnOnCaptions();\n });\n };\n}\n\nexport default VoiceaChannel;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["VoiceaChannel","args","VOICEA","voiceaPayload","type","TRANSCRIPTION_TYPE","TRANSCRIPT_INTERIM_RESULTS","Trigger","trigger","file","function","EVENT_TRIGGERS","NEW_CAPTION","isFinal","transcriptId","transcript_id","translations","transcript","csis","transcripts","text","data","transcriptLanguageCode","transcript_language_code","TRANSCRIPT_FINAL_RESULT","timestamp","millisToMinutesAndSeconds","end_millis","HIGHLIGHT_CREATED","highlight","highlightId","highlight_id","highlightLabel","highlight_label","highlightSource","highlight_source","EVA_THANKS","EVA_COMMAND","isListening","command_response","EVA_WAKE","EVA_CANCEL","statusCode","CAPTION_LANGUAGE_UPDATE","errorCode","errorMessage","message","voiceaLanguageOptions","captionLanguages","translation","allowed_languages","maxLanguages","max_languages","spokenLanguages","ASR","spoken_languages","VOICEA_ANNOUNCEMENT","hasVoiceaJoined","webex","internal","llm","isConnected","listenToEvents","socket","send","id","seqNum","recipients","route","getBinding","headers","clientPayload","version","eventType","relayType","VOICEA_RELAY_TYPES","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","languageCode","request","method","url","getLocusUrl","body","then","SPOKEN_LANGUAGE_UPDATE","to","vmcDeviceId","translationLanguage","TRANSLATION_REQUEST","areCaptionsEnabled","undefined","transcribe","caption","CAPTIONS_TURNED_ON","sendAnnouncement","activate","isTranscribingEnabled","transcribing","TRANSCRIBING_ON","TRANSCRIBING_OFF","turnOnCaptions","on","e","sequenceNumber","ANNOUNCEMENT","from","processAnnouncementMessage","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","WebexPlugin"],"sources":["voicea.ts"],"sourcesContent":["import uuid from 'uuid';\nimport {TriggerProxy as Trigger} from '@webex/plugin-meetings';\nimport {WebexPlugin, config} from '@webex/webex-core';\n\nimport {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE, VOICEA} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, IVoiceaChannel} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * VoiceaChannel to hold single instance of LLM\n */\nexport class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {\n namespace = VOICEA;\n\n private seqNum: number;\n\n private hasVoiceaJoined: boolean;\n\n private areCaptionsEnabled: boolean;\n\n private isTranscribingEnabled:boolean;\n\n private vmcDeviceId: string;\n\n /**\n * Listen to websocket messages\n */\n private listenToEvents() {\n this.webex.internal.llm.on('event:relay.event', (e) => {\n this.seqNum = e.sequenceNumber + 1;\n switch (e.data.relayType) {\n case VOICEA_RELAY_TYPES.ANNOUNCEMENT:\n this.vmcDeviceId = e.headers.from;\n this.hasVoiceaJoined = true;\n this.processAnnouncementMessage(e.data.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:\n this.processCaptionLanguageResponse(e.data.voiceaPayload);\n break;\n case VOICEA_RELAY_TYPES.TRANSCRIPTION:\n this.processTranscription(e.data.voiceaPayload);\n break;\n default:\n break;\n }\n });\n }\n\n /**\n * Initializes Voicea plugin\n * @param {any} args\n */\n constructor(...args) {\n super(...args);\n this.seqNum = 1;\n this.hasVoiceaJoined = false;\n this.areCaptionsEnabled = false;\n this.isTranscribingEnabled = false;\n this.vmcDeviceId = undefined;\n }\n\n /**\n * Process Transcript and send alert\n * @param {TranscriptionResponse} voiceaPayload\n * @returns {void}\n */\n private processTranscription = (voiceaPayload: TranscriptionResponse): void => {\n switch (voiceaPayload.type) {\n case TRANSCRIPTION_TYPE.TRANSCRIPT_INTERIM_RESULTS:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n translations: voiceaPayload.translations,\n transcript: {\n csis: voiceaPayload.transcripts[0] ? voiceaPayload.transcripts[0].csis : [],\n text: voiceaPayload.data,\n transcriptLanguageCode: voiceaPayload.transcripts[0].transcript_language_code\n },\n });\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.NEW_CAPTION, {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\n translations: voiceaPayload.translations,\n transcript: {\n csis: voiceaPayload.csis,\n text: voiceaPayload.transcript.text,\n transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code\n },\n timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis)\n });\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.HIGHLIGHT_CREATED, {\n csis: voiceaPayload.highlight.csis,\n highlightId: voiceaPayload.highlight.highlight_id,\n text: voiceaPayload.highlight.transcript,\n highlightLabel: voiceaPayload.highlight.highlight_label,\n highlightSource: voiceaPayload.highlight.highlight_source,\n timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis)\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: false, text: voiceaPayload.command_response\n });\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processTranscription'\n },\n EVENT_TRIGGERS.EVA_COMMAND, {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE\n });\n break;\n\n default:\n break;\n }\n };\n\n /**\n * Processes Caption Language Response\n * @param {CaptionLanguageResponse} voiceaPayload\n * @returns {void}\n */\n private processCaptionLanguageResponse = (voiceaPayload: CaptionLanguageResponse):void => {\n if (voiceaPayload.statusCode === 200) {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processCaptionLanguageResponse'\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: 200});\n }\n else {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'processCaptionLanguageResponse'\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message});\n }\n };\n\n /**\n * processes voicea announcement response and triggers event\n * @param {Object} voiceaPayload\n * @returns {void}\n */\n private processAnnouncementMessage = (voiceaPayload: AnnouncementPayload):void => {\n const voiceaLanguageOptions = {\n captionLanguages: voiceaPayload?.translation?.allowed_languages ?? [],\n maxLanguages: voiceaPayload?.translation?.max_languages ?? 0,\n spokenLanguages: voiceaPayload?.ASR?.spoken_languages ?? [],\n };\n\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processAnnouncementMessage'\n },\n EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT,\n voiceaLanguageOptions\n );\n };\n\n\n /**\n * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n private sendAnnouncement = ():void => {\n if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;\n\n this.listenToEvents();\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.webex.internal.llm.getBinding(),\n },\n headers: {},\n data: {\n clientPayload: {\n version: 'v2',\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.CLIENT_ANNOUNCEMENT,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`\n });\n this.seqNum += 1;\n };\n\n /**\n * Set Spoken Language for the meeting\n * @param {string} languageCode\n * @returns {Promise}\n */\n public setSpokenLanguage = (languageCode: string):Promise<void> => this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n languageCode\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'setSpokenLanguage'\n },\n EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,\n {languageCode});\n });\n\n /**\n * Request Language translation\n * @param {string} languageCode\n * @returns {void}\n */\n public requestLanguage = (languageCode: string): void => {\n if (!this.webex.internal.llm.isConnected()) return;\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n route: this.webex.internal.llm.getBinding(),\n },\n headers: {\n to: this.vmcDeviceId,\n },\n data: {\n clientPayload: {\n translationLanguage: languageCode,\n id: uuid.v4(),\n },\n eventType: 'relay.event',\n relayType: VOICEA_RELAY_TYPES.TRANSLATION_REQUEST,\n },\n trackingId: `${config.trackingIdPrefix}_${uuid.v4().toString()}`\n });\n this.seqNum += 1;\n };\n\n /**\n * Turn on Captions\n * @returns {Promise}\n */\n public turnOnCaptions = async (): undefined | Promise<void> => {\n if (this.hasVoiceaJoined && this.areCaptionsEnabled) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {caption: true}\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'turnOnCaptions'\n },\n EVENT_TRIGGERS.CAPTIONS_TURNED_ON);\n this.areCaptionsEnabled = true;\n this.sendAnnouncement();\n });\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {bool} activate if true transcribing is turned on\n * @returns {Promise}\n */\n public toggleTranscribing = async (activate:boolean):undefined|Promise<void> => {\n if (this.isTranscribingEnabled === activate) return undefined;\n\n return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {transcribing: activate}\n }\n }).then(() => {\n Trigger.trigger(this, {\n file: 'voicea',\n function: 'toggleTranscribing'\n },\n activate ? EVENT_TRIGGERS.TRANSCRIBING_ON : EVENT_TRIGGERS.TRANSCRIBING_OFF);\n this.isTranscribingEnabled = activate;\n if (activate && !this.areCaptionsEnabled && !this.hasVoiceaJoined) this.turnOnCaptions();\n });\n };\n}\n\nexport default VoiceaChannel;\n"],"mappings":"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"}
|
package/dist/voicea.types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["voicea.types.ts"],"sourcesContent":["/* eslint-disable camelcase */\n/* eslint-disable no-undef */\n\n/**\n * Type for payload\n */\ninterface AnnouncementPayload {\n translation:{\n max_languages: number;\n allowed_languages: string[]\n };\n\n ASR: {\n spoken_languages: string[];\n };\n}\n\n// eslint-disable-next-line no-undef\ntype TRANSCRIPTION_TYPES = 'unknown'|\n'eva_wake' |\n'eva_thanks' |\n'eva_cancel' |\n'highlight_created'|\n'transcript_interim_results'|\n'transcript_final_result';\n\n/**\n * Class for an Transcription Object\n */\ninterface Transcription {\n start_millis:number;\n end_millis:number;\n text:string;\n transcript_language_code: string;\n translations:{[x:string]:string};\n csis:number[];\n}\n\n/**\n * Highlights\n */\n interface Highlight {\n highlight_id: string;\n transcript: string;\n highlight_label: string;\n highlight_source: string;\n start_millis:number;\n end_millis:number;\n csis:number[];\n}\n/**\n * Type for Transcription message\n */\ninterface TranscriptionResponse {\n type: TRANSCRIPTION_TYPES;\n transcript_id: string;\n translations?: {[x:string]:string};\n transcripts?: Transcription[];\n transcript?: Transcription;\n highlight?: Highlight;\n csis: number[];\n data:string;\n command_response: string;\n}\n/**\n * Type for CaptionLanguageResponse\n */\ninterface CaptionLanguageResponse {\n requestId: string;\n statusCode: number;\n errorCode:number;\n message:string;\n}\n\ninterface IVoiceaChannel {\n setSpokenLanguage: (languageCode: string) => Promise<void>;\n requestLanguage: (languageCode: string) => void;\n turnOnCaptions: () => undefined | Promise<void>;\n toggleTranscribing: (activate:boolean) => undefined|Promise<void>;\n}\nexport {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, Transcription, Highlight, IVoiceaChannel};\n"],"mappings":""}
|
|
1
|
+
{"version":3,"names":[],"sources":["voicea.types.ts"],"sourcesContent":["/* eslint-disable camelcase */\n/* eslint-disable no-undef */\n\n/**\n * Type for payload\n */\ninterface AnnouncementPayload {\n translation:{\n max_languages: number;\n allowed_languages: string[]\n };\n\n ASR: {\n spoken_languages: string[];\n };\n}\n\n// eslint-disable-next-line no-undef\ntype TRANSCRIPTION_TYPES = 'unknown'|\n'eva_wake' |\n'eva_thanks' |\n'eva_cancel' |\n'highlight_created'|\n'transcript_interim_results'|\n'transcript_final_result';\n\n/**\n * Class for an Transcription Object\n */\ninterface Transcription {\n start_millis:number;\n end_millis:number;\n text:string;\n transcript_language_code: string;\n translations:{[x:string]:string};\n csis:number[];\n last_packet_timestamp_ms: number;\n}\n\n/**\n * Highlights\n */\n interface Highlight {\n highlight_id: string;\n transcript: string;\n highlight_label: string;\n highlight_source: string;\n start_millis:number;\n end_millis:number;\n csis:number[];\n}\n/**\n * Type for Transcription message\n */\ninterface TranscriptionResponse {\n type: TRANSCRIPTION_TYPES;\n transcript_id: string;\n translations?: {[x:string]:string};\n transcripts?: Transcription[];\n transcript?: Transcription;\n highlight?: Highlight;\n csis: number[];\n data:string;\n command_response: string;\n}\n/**\n * Type for CaptionLanguageResponse\n */\ninterface CaptionLanguageResponse {\n requestId: string;\n statusCode: number;\n errorCode:number;\n message:string;\n}\n\ninterface IVoiceaChannel {\n setSpokenLanguage: (languageCode: string) => Promise<void>;\n requestLanguage: (languageCode: string) => void;\n turnOnCaptions: () => undefined | Promise<void>;\n toggleTranscribing: (activate:boolean) => undefined|Promise<void>;\n}\nexport {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, Transcription, Highlight, IVoiceaChannel};\n"],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-voicea",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.26.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,10 +11,9 @@
|
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@babel/runtime-corejs2": "^7.14.8",
|
|
14
|
-
"@webex/webex-core": "2.
|
|
14
|
+
"@webex/webex-core": "2.26.1",
|
|
15
15
|
"uuid": "^3.3.2",
|
|
16
|
-
"@webex/
|
|
17
|
-
"@webex/plugin-meetings": "2.25.0",
|
|
16
|
+
"@webex/plugin-meetings": "2.26.1",
|
|
18
17
|
"envify": "^4.1.0"
|
|
19
18
|
},
|
|
20
19
|
"browserify": {
|
package/src/constants.ts
CHANGED
package/src/index.ts
CHANGED
package/src/voicea.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import uuid from 'uuid';
|
|
2
|
-
import LLMChannel from '@webex/internal-plugin-llm';
|
|
3
2
|
import {TriggerProxy as Trigger} from '@webex/plugin-meetings';
|
|
4
|
-
import {config} from '@webex/webex-core';
|
|
3
|
+
import {WebexPlugin, config} from '@webex/webex-core';
|
|
5
4
|
|
|
6
|
-
import {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE} from './constants';
|
|
5
|
+
import {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE, VOICEA} from './constants';
|
|
7
6
|
// eslint-disable-next-line no-unused-vars
|
|
8
7
|
import {AnnouncementPayload, CaptionLanguageResponse, TranscriptionResponse, IVoiceaChannel} from './voicea.types';
|
|
9
8
|
import {millisToMinutesAndSeconds} from './utils';
|
|
9
|
+
|
|
10
10
|
/**
|
|
11
11
|
* VoiceaChannel to hold single instance of LLM
|
|
12
12
|
*/
|
|
13
|
-
export class VoiceaChannel extends
|
|
13
|
+
export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
14
|
+
namespace = VOICEA;
|
|
15
|
+
|
|
14
16
|
private seqNum: number;
|
|
15
17
|
|
|
16
18
|
private hasVoiceaJoined: boolean;
|
|
@@ -22,30 +24,22 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
22
24
|
private vmcDeviceId: string;
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @param {any} args
|
|
27
|
+
* Listen to websocket messages
|
|
27
28
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
this.seqNum = 1;
|
|
31
|
-
this.hasVoiceaJoined = false;
|
|
32
|
-
this.areCaptionsEnabled = false;
|
|
33
|
-
this.isTranscribingEnabled = false;
|
|
34
|
-
this.vmcDeviceId = undefined;
|
|
35
|
-
|
|
36
|
-
this.on('event:relay.event', (e) => {
|
|
29
|
+
private listenToEvents() {
|
|
30
|
+
this.webex.internal.llm.on('event:relay.event', (e) => {
|
|
37
31
|
this.seqNum = e.sequenceNumber + 1;
|
|
38
32
|
switch (e.data.relayType) {
|
|
39
33
|
case VOICEA_RELAY_TYPES.ANNOUNCEMENT:
|
|
40
34
|
this.vmcDeviceId = e.headers.from;
|
|
41
35
|
this.hasVoiceaJoined = true;
|
|
42
|
-
this.processAnnouncementMessage(e.voiceaPayload);
|
|
36
|
+
this.processAnnouncementMessage(e.data.voiceaPayload);
|
|
43
37
|
break;
|
|
44
38
|
case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:
|
|
45
|
-
this.processCaptionLanguageResponse(e.voiceaPayload);
|
|
39
|
+
this.processCaptionLanguageResponse(e.data.voiceaPayload);
|
|
46
40
|
break;
|
|
47
41
|
case VOICEA_RELAY_TYPES.TRANSCRIPTION:
|
|
48
|
-
this.processTranscription(e.voiceaPayload);
|
|
42
|
+
this.processTranscription(e.data.voiceaPayload);
|
|
49
43
|
break;
|
|
50
44
|
default:
|
|
51
45
|
break;
|
|
@@ -53,6 +47,19 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
53
47
|
});
|
|
54
48
|
}
|
|
55
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Initializes Voicea plugin
|
|
52
|
+
* @param {any} args
|
|
53
|
+
*/
|
|
54
|
+
constructor(...args) {
|
|
55
|
+
super(...args);
|
|
56
|
+
this.seqNum = 1;
|
|
57
|
+
this.hasVoiceaJoined = false;
|
|
58
|
+
this.areCaptionsEnabled = false;
|
|
59
|
+
this.isTranscribingEnabled = false;
|
|
60
|
+
this.vmcDeviceId = undefined;
|
|
61
|
+
}
|
|
62
|
+
|
|
56
63
|
/**
|
|
57
64
|
* Process Transcript and send alert
|
|
58
65
|
* @param {TranscriptionResponse} voiceaPayload
|
|
@@ -70,8 +77,9 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
70
77
|
transcriptId: voiceaPayload.transcript_id,
|
|
71
78
|
translations: voiceaPayload.translations,
|
|
72
79
|
transcript: {
|
|
73
|
-
csis: voiceaPayload.csis,
|
|
74
|
-
text: voiceaPayload.data
|
|
80
|
+
csis: voiceaPayload.transcripts[0] ? voiceaPayload.transcripts[0].csis : [],
|
|
81
|
+
text: voiceaPayload.data,
|
|
82
|
+
transcriptLanguageCode: voiceaPayload.transcripts[0].transcript_language_code
|
|
75
83
|
},
|
|
76
84
|
});
|
|
77
85
|
break;
|
|
@@ -87,9 +95,10 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
87
95
|
translations: voiceaPayload.translations,
|
|
88
96
|
transcript: {
|
|
89
97
|
csis: voiceaPayload.csis,
|
|
90
|
-
text: voiceaPayload.
|
|
98
|
+
text: voiceaPayload.transcript.text,
|
|
99
|
+
transcriptLanguageCode: voiceaPayload.transcript.transcript_language_code
|
|
91
100
|
},
|
|
92
|
-
timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis
|
|
101
|
+
timestamp: millisToMinutesAndSeconds(voiceaPayload.transcript.end_millis)
|
|
93
102
|
});
|
|
94
103
|
break;
|
|
95
104
|
|
|
@@ -104,7 +113,7 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
104
113
|
text: voiceaPayload.highlight.transcript,
|
|
105
114
|
highlightLabel: voiceaPayload.highlight.highlight_label,
|
|
106
115
|
highlightSource: voiceaPayload.highlight.highlight_source,
|
|
107
|
-
timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis
|
|
116
|
+
timestamp: millisToMinutesAndSeconds(voiceaPayload.highlight.end_millis)
|
|
108
117
|
});
|
|
109
118
|
break;
|
|
110
119
|
|
|
@@ -185,12 +194,14 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
185
194
|
* @returns {void}
|
|
186
195
|
*/
|
|
187
196
|
private sendAnnouncement = ():void => {
|
|
188
|
-
if (this.hasVoiceaJoined) return;
|
|
189
|
-
|
|
197
|
+
if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;
|
|
198
|
+
|
|
199
|
+
this.listenToEvents();
|
|
200
|
+
this.webex.internal.llm.socket.send({
|
|
190
201
|
id: `${this.seqNum}`,
|
|
191
202
|
type: 'publishRequest',
|
|
192
203
|
recipients: {
|
|
193
|
-
route: this.getBinding(),
|
|
204
|
+
route: this.webex.internal.llm.getBinding(),
|
|
194
205
|
},
|
|
195
206
|
headers: {},
|
|
196
207
|
data: {
|
|
@@ -212,7 +223,7 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
212
223
|
*/
|
|
213
224
|
public setSpokenLanguage = (languageCode: string):Promise<void> => this.request({
|
|
214
225
|
method: 'PUT',
|
|
215
|
-
url: `${this.getLocusUrl()}/controls/`,
|
|
226
|
+
url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
|
|
216
227
|
body: {
|
|
217
228
|
languageCode
|
|
218
229
|
}
|
|
@@ -231,11 +242,12 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
231
242
|
* @returns {void}
|
|
232
243
|
*/
|
|
233
244
|
public requestLanguage = (languageCode: string): void => {
|
|
234
|
-
this.
|
|
245
|
+
if (!this.webex.internal.llm.isConnected()) return;
|
|
246
|
+
this.webex.internal.llm.socket.send({
|
|
235
247
|
id: `${this.seqNum}`,
|
|
236
248
|
type: 'publishRequest',
|
|
237
249
|
recipients: {
|
|
238
|
-
route: this.getBinding(),
|
|
250
|
+
route: this.webex.internal.llm.getBinding(),
|
|
239
251
|
},
|
|
240
252
|
headers: {
|
|
241
253
|
to: this.vmcDeviceId,
|
|
@@ -262,7 +274,7 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
262
274
|
|
|
263
275
|
return this.request({
|
|
264
276
|
method: 'PUT',
|
|
265
|
-
url: `${this.getLocusUrl()}/controls/`,
|
|
277
|
+
url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
|
|
266
278
|
body: {
|
|
267
279
|
transcribe: {caption: true}
|
|
268
280
|
}
|
|
@@ -287,7 +299,7 @@ export class VoiceaChannel extends LLMChannel implements IVoiceaChannel {
|
|
|
287
299
|
|
|
288
300
|
return this.request({
|
|
289
301
|
method: 'PUT',
|
|
290
|
-
url: `${this.getLocusUrl()}/controls/`,
|
|
302
|
+
url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
|
|
291
303
|
body: {
|
|
292
304
|
transcribe: {transcribing: activate}
|
|
293
305
|
}
|
package/src/voicea.types.ts
CHANGED
package/test/unit/spec/voicea.js
CHANGED
|
@@ -10,7 +10,6 @@ import {EVENT_TRIGGERS} from '../../../src/constants';
|
|
|
10
10
|
|
|
11
11
|
describe('plugin-voicea', () => {
|
|
12
12
|
const locusUrl = 'locusUrl';
|
|
13
|
-
const datachannelUrl = 'datachannelUrl';
|
|
14
13
|
|
|
15
14
|
describe('voicea', () => {
|
|
16
15
|
let webex, voiceaService;
|
|
@@ -27,6 +26,10 @@ describe('plugin-voicea', () => {
|
|
|
27
26
|
|
|
28
27
|
voiceaService = webex.internal.voicea;
|
|
29
28
|
voiceaService.connect = sinon.stub().resolves(true);
|
|
29
|
+
voiceaService.webex.internal.llm.isConnected = sinon.stub().returns(true);
|
|
30
|
+
voiceaService.webex.internal.llm.getBinding = sinon.stub().returns(undefined);
|
|
31
|
+
voiceaService.webex.internal.llm.getLocusUrl = sinon.stub().returns(locusUrl);
|
|
32
|
+
|
|
30
33
|
voiceaService.request = sinon.stub().resolves({
|
|
31
34
|
headers: {},
|
|
32
35
|
body: ''
|
|
@@ -41,15 +44,18 @@ describe('plugin-voicea', () => {
|
|
|
41
44
|
|
|
42
45
|
describe('#sendAnnouncement', () => {
|
|
43
46
|
beforeEach(async () => {
|
|
44
|
-
await voiceaService.registerAndConnect(locusUrl, datachannelUrl);
|
|
45
47
|
const mockWebSocket = new MockWebSocket();
|
|
46
48
|
|
|
47
|
-
voiceaService.socket = mockWebSocket;
|
|
49
|
+
voiceaService.webex.internal.llm.socket = mockWebSocket;
|
|
48
50
|
});
|
|
49
51
|
|
|
50
52
|
it("sends announcement if voicea hasn't joined", () => {
|
|
53
|
+
const spy = sinon.spy(voiceaService, 'listenToEvents');
|
|
54
|
+
|
|
51
55
|
voiceaService.sendAnnouncement();
|
|
52
|
-
assert.
|
|
56
|
+
assert.calledOnce(spy);
|
|
57
|
+
|
|
58
|
+
assert.calledOnceWithExactly(voiceaService.webex.internal.llm.socket.send, {
|
|
53
59
|
id: '1',
|
|
54
60
|
type: 'publishRequest',
|
|
55
61
|
recipients: {route: undefined},
|
|
@@ -83,6 +89,7 @@ describe('plugin-voicea', () => {
|
|
|
83
89
|
const spy = sinon.spy();
|
|
84
90
|
|
|
85
91
|
voiceaService.on(EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, spy);
|
|
92
|
+
voiceaService.listenToEvents();
|
|
86
93
|
voiceaService.processAnnouncementMessage(voiceaPayload);
|
|
87
94
|
assert.calledOnceWithExactly(spy, {
|
|
88
95
|
captionLanguages: ['af', 'am'],
|
|
@@ -95,6 +102,7 @@ describe('plugin-voicea', () => {
|
|
|
95
102
|
const spy = sinon.spy();
|
|
96
103
|
|
|
97
104
|
voiceaService.on(EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, spy);
|
|
105
|
+
voiceaService.listenToEvents();
|
|
98
106
|
await voiceaService.processAnnouncementMessage({});
|
|
99
107
|
assert.calledOnceWithExactly(spy, {
|
|
100
108
|
captionLanguages: [],
|
|
@@ -106,16 +114,15 @@ describe('plugin-voicea', () => {
|
|
|
106
114
|
|
|
107
115
|
describe('#requestLanguage', () => {
|
|
108
116
|
beforeEach(async () => {
|
|
109
|
-
await voiceaService.registerAndConnect(locusUrl, datachannelUrl);
|
|
110
117
|
const mockWebSocket = new MockWebSocket();
|
|
111
118
|
|
|
112
|
-
voiceaService.socket = mockWebSocket;
|
|
119
|
+
voiceaService.webex.internal.llm.socket = mockWebSocket;
|
|
113
120
|
});
|
|
114
121
|
|
|
115
122
|
it('requests caption language', () => {
|
|
116
123
|
voiceaService.requestLanguage('en');
|
|
117
124
|
|
|
118
|
-
assert.calledOnceWithExactly(voiceaService.socket.send, {
|
|
125
|
+
assert.calledOnceWithExactly(voiceaService.webex.internal.llm.socket.send, {
|
|
119
126
|
id: '1',
|
|
120
127
|
type: 'publishRequest',
|
|
121
128
|
recipients: {route: undefined},
|
|
@@ -134,15 +141,12 @@ describe('plugin-voicea', () => {
|
|
|
134
141
|
});
|
|
135
142
|
|
|
136
143
|
describe('#setSpokenLanguage', () => {
|
|
137
|
-
beforeEach(async () => {
|
|
138
|
-
await voiceaService.registerAndConnect(locusUrl, datachannelUrl);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
144
|
it('sets spoken language', async () => {
|
|
142
145
|
const languageCode = 'en';
|
|
143
146
|
const triggerSpy = sinon.spy();
|
|
144
147
|
|
|
145
148
|
voiceaService.on(EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, triggerSpy);
|
|
149
|
+
voiceaService.listenToEvents();
|
|
146
150
|
await voiceaService.setSpokenLanguage(languageCode);
|
|
147
151
|
|
|
148
152
|
assert.calledOnceWithExactly(triggerSpy, {languageCode});
|
|
@@ -157,11 +161,9 @@ describe('plugin-voicea', () => {
|
|
|
157
161
|
|
|
158
162
|
describe('#turnOnCaptions', () => {
|
|
159
163
|
beforeEach(async () => {
|
|
160
|
-
await voiceaService.registerAndConnect(locusUrl, datachannelUrl);
|
|
161
|
-
|
|
162
164
|
const mockWebSocket = new MockWebSocket();
|
|
163
165
|
|
|
164
|
-
voiceaService.socket = mockWebSocket;
|
|
166
|
+
voiceaService.webex.internal.llm.socket = mockWebSocket;
|
|
165
167
|
});
|
|
166
168
|
|
|
167
169
|
it('turns on captions', async () => {
|
|
@@ -170,6 +172,8 @@ describe('plugin-voicea', () => {
|
|
|
170
172
|
const triggerSpy = sinon.spy();
|
|
171
173
|
|
|
172
174
|
voiceaService.on(EVENT_TRIGGERS.CAPTIONS_TURNED_ON, triggerSpy);
|
|
175
|
+
voiceaService.listenToEvents();
|
|
176
|
+
|
|
173
177
|
await voiceaService.turnOnCaptions();
|
|
174
178
|
sinon.assert.calledWith(voiceaService.request, sinon.match({
|
|
175
179
|
method: 'PUT',
|
|
@@ -178,6 +182,7 @@ describe('plugin-voicea', () => {
|
|
|
178
182
|
}));
|
|
179
183
|
|
|
180
184
|
assert.calledOnceWithExactly(triggerSpy, undefined);
|
|
185
|
+
|
|
181
186
|
assert.calledOnce(announcementSpy);
|
|
182
187
|
});
|
|
183
188
|
|
|
@@ -185,7 +190,7 @@ describe('plugin-voicea', () => {
|
|
|
185
190
|
await voiceaService.turnOnCaptions();
|
|
186
191
|
|
|
187
192
|
// eslint-disable-next-line no-underscore-dangle
|
|
188
|
-
voiceaService._emit('event:relay.event', {headers: {from: 'ws'},
|
|
193
|
+
voiceaService.webex.internal.llm._emit('event:relay.event', {headers: {from: 'ws'}, data: {relayType: 'voicea.annc', voiceaPayload: {}}});
|
|
189
194
|
|
|
190
195
|
const response = await voiceaService.turnOnCaptions();
|
|
191
196
|
|
|
@@ -195,11 +200,9 @@ describe('plugin-voicea', () => {
|
|
|
195
200
|
|
|
196
201
|
describe('#toggleTranscribing', () => {
|
|
197
202
|
beforeEach(async () => {
|
|
198
|
-
await voiceaService.registerAndConnect(locusUrl, datachannelUrl);
|
|
199
|
-
|
|
200
203
|
const mockWebSocket = new MockWebSocket();
|
|
201
204
|
|
|
202
|
-
voiceaService.socket = mockWebSocket;
|
|
205
|
+
voiceaService.webex.internal.llm.socket = mockWebSocket;
|
|
203
206
|
});
|
|
204
207
|
|
|
205
208
|
it('turns on transcribing with CC enabled', async () => {
|
|
@@ -208,11 +211,13 @@ describe('plugin-voicea', () => {
|
|
|
208
211
|
const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
|
|
209
212
|
|
|
210
213
|
// eslint-disable-next-line no-underscore-dangle
|
|
211
|
-
voiceaService._emit('event:relay.event', {headers: {from: 'ws'},
|
|
214
|
+
voiceaService.webex.internal.llm._emit('event:relay.event', {headers: {from: 'ws'}, data: {relayType: 'voicea.annc', voiceaPayload: {}}});
|
|
212
215
|
|
|
213
216
|
const triggerSpy = sinon.spy();
|
|
214
217
|
|
|
215
218
|
voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_ON, triggerSpy);
|
|
219
|
+
voiceaService.listenToEvents();
|
|
220
|
+
|
|
216
221
|
await voiceaService.toggleTranscribing(true);
|
|
217
222
|
sinon.assert.calledWith(voiceaService.request, sinon.match({
|
|
218
223
|
method: 'PUT',
|
|
@@ -230,6 +235,8 @@ describe('plugin-voicea', () => {
|
|
|
230
235
|
const triggerSpy = sinon.spy();
|
|
231
236
|
|
|
232
237
|
voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_ON, triggerSpy);
|
|
238
|
+
voiceaService.listenToEvents();
|
|
239
|
+
|
|
233
240
|
await voiceaService.toggleTranscribing(true);
|
|
234
241
|
sinon.assert.calledWith(voiceaService.request, sinon.match({
|
|
235
242
|
method: 'PUT',
|
|
@@ -249,6 +256,8 @@ describe('plugin-voicea', () => {
|
|
|
249
256
|
const triggerSpy = sinon.spy();
|
|
250
257
|
|
|
251
258
|
voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_OFF, triggerSpy);
|
|
259
|
+
voiceaService.listenToEvents();
|
|
260
|
+
|
|
252
261
|
await voiceaService.toggleTranscribing(false);
|
|
253
262
|
sinon.assert.calledWith(voiceaService.request, sinon.match({
|
|
254
263
|
method: 'PUT',
|
|
@@ -268,12 +277,13 @@ describe('plugin-voicea', () => {
|
|
|
268
277
|
|
|
269
278
|
voiceaService.on(EVENT_TRIGGERS.TRANSCRIBING_OFF, triggerSpy);
|
|
270
279
|
|
|
280
|
+
|
|
271
281
|
await voiceaService.toggleTranscribing(true);
|
|
272
282
|
|
|
273
283
|
assert.notCalled(triggerSpy);
|
|
274
284
|
assert.notCalled(announcementSpy);
|
|
275
285
|
|
|
276
|
-
|
|
286
|
+
assert.calledTwice(voiceaService.request);
|
|
277
287
|
});
|
|
278
288
|
});
|
|
279
289
|
|
|
@@ -283,24 +293,29 @@ describe('plugin-voicea', () => {
|
|
|
283
293
|
const functionSpy = sinon.spy(voiceaService, 'processCaptionLanguageResponse');
|
|
284
294
|
|
|
285
295
|
voiceaService.on(EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, triggerSpy);
|
|
296
|
+
voiceaService.listenToEvents();
|
|
286
297
|
|
|
287
298
|
// eslint-disable-next-line no-underscore-dangle
|
|
288
|
-
voiceaService._emit('event:relay.event', {
|
|
299
|
+
voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
289
300
|
headers: {from: 'ws'},
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
301
|
+
data: {
|
|
302
|
+
relayType: 'voicea.transl.rsp',
|
|
303
|
+
voiceaPayload: {
|
|
304
|
+
statusCode: 200
|
|
305
|
+
}
|
|
306
|
+
}
|
|
294
307
|
});
|
|
295
308
|
|
|
296
309
|
assert.calledOnceWithExactly(triggerSpy, {statusCode: 200});
|
|
297
310
|
assert.calledOnce(functionSpy);
|
|
298
311
|
});
|
|
312
|
+
|
|
299
313
|
it('responds to process caption language for a failed response', async () => {
|
|
300
314
|
const triggerSpy = sinon.spy();
|
|
301
315
|
const functionSpy = sinon.spy(voiceaService, 'processCaptionLanguageResponse');
|
|
302
316
|
|
|
303
317
|
voiceaService.on(EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE, triggerSpy);
|
|
318
|
+
voiceaService.listenToEvents();
|
|
304
319
|
|
|
305
320
|
const payload = {
|
|
306
321
|
errorCode: 300,
|
|
@@ -308,10 +323,9 @@ describe('plugin-voicea', () => {
|
|
|
308
323
|
};
|
|
309
324
|
|
|
310
325
|
// eslint-disable-next-line no-underscore-dangle
|
|
311
|
-
voiceaService._emit('event:relay.event', {
|
|
326
|
+
voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
312
327
|
headers: {from: 'ws'},
|
|
313
|
-
voiceaPayload: payload
|
|
314
|
-
data: {relayType: 'voicea.transl.rsp'}
|
|
328
|
+
data: {relayType: 'voicea.transl.rsp', voiceaPayload: payload}
|
|
315
329
|
});
|
|
316
330
|
assert.calledOnce(functionSpy);
|
|
317
331
|
assert.calledOnceWithExactly(triggerSpy, {statusCode: 300, errorMessage: 'error text'});
|
|
@@ -324,6 +338,7 @@ describe('plugin-voicea', () => {
|
|
|
324
338
|
beforeEach(() => {
|
|
325
339
|
triggerSpy = sinon.spy();
|
|
326
340
|
functionSpy = sinon.spy(voiceaService, 'processTranscription');
|
|
341
|
+
voiceaService.listenToEvents();
|
|
327
342
|
});
|
|
328
343
|
|
|
329
344
|
it('processes interim transcription', async () => {
|
|
@@ -366,15 +381,14 @@ describe('plugin-voicea', () => {
|
|
|
366
381
|
};
|
|
367
382
|
|
|
368
383
|
// eslint-disable-next-line no-underscore-dangle
|
|
369
|
-
await voiceaService._emit('event:relay.event', {
|
|
384
|
+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
370
385
|
headers: {from: 'ws'},
|
|
371
|
-
voiceaPayload
|
|
372
|
-
data: {relayType: 'voicea.transcription'}
|
|
386
|
+
data: {relayType: 'voicea.transcription', voiceaPayload}
|
|
373
387
|
});
|
|
374
388
|
|
|
375
389
|
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
|
|
376
390
|
assert.calledOnceWithExactly(triggerSpy, {
|
|
377
|
-
isFinal: false, transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e', translations: undefined, transcript: {text: 'Hello.', csis: [3556942592]}
|
|
391
|
+
isFinal: false, transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e', translations: undefined, transcript: {text: 'Hello.', csis: [3556942592], transcriptLanguageCode: 'en'}
|
|
378
392
|
});
|
|
379
393
|
});
|
|
380
394
|
|
|
@@ -438,15 +452,22 @@ describe('plugin-voicea', () => {
|
|
|
438
452
|
};
|
|
439
453
|
|
|
440
454
|
// eslint-disable-next-line no-underscore-dangle
|
|
441
|
-
await voiceaService._emit('event:relay.event', {
|
|
455
|
+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
442
456
|
headers: {from: 'ws'},
|
|
443
|
-
voiceaPayload
|
|
444
|
-
data: {relayType: 'voicea.transcription'}
|
|
457
|
+
data: {relayType: 'voicea.transcription', voiceaPayload}
|
|
445
458
|
});
|
|
446
459
|
|
|
447
460
|
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
|
|
448
461
|
assert.calledOnceWithExactly(triggerSpy, {
|
|
449
|
-
isFinal: true,
|
|
462
|
+
isFinal: true,
|
|
463
|
+
transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
|
|
464
|
+
translations: undefined,
|
|
465
|
+
transcript: {
|
|
466
|
+
csis: [3556942592],
|
|
467
|
+
text: 'Hello?',
|
|
468
|
+
transcriptLanguageCode: 'en'
|
|
469
|
+
},
|
|
470
|
+
timestamp: '0:13'
|
|
450
471
|
});
|
|
451
472
|
});
|
|
452
473
|
|
|
@@ -472,10 +493,9 @@ describe('plugin-voicea', () => {
|
|
|
472
493
|
};
|
|
473
494
|
|
|
474
495
|
// eslint-disable-next-line no-underscore-dangle
|
|
475
|
-
await voiceaService._emit('event:relay.event', {
|
|
496
|
+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
476
497
|
headers: {from: 'ws'},
|
|
477
|
-
voiceaPayload
|
|
478
|
-
data: {relayType: 'voicea.transcription'}
|
|
498
|
+
data: {relayType: 'voicea.transcription', voiceaPayload}
|
|
479
499
|
});
|
|
480
500
|
|
|
481
501
|
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
|
|
@@ -498,10 +518,9 @@ describe('plugin-voicea', () => {
|
|
|
498
518
|
};
|
|
499
519
|
|
|
500
520
|
// eslint-disable-next-line no-underscore-dangle
|
|
501
|
-
await voiceaService._emit('event:relay.event', {
|
|
521
|
+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
502
522
|
headers: {from: 'ws'},
|
|
503
|
-
voiceaPayload
|
|
504
|
-
data: {relayType: 'voicea.transcription'}
|
|
523
|
+
data: {relayType: 'voicea.transcription', voiceaPayload}
|
|
505
524
|
});
|
|
506
525
|
|
|
507
526
|
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
|
|
@@ -524,13 +543,13 @@ describe('plugin-voicea', () => {
|
|
|
524
543
|
};
|
|
525
544
|
|
|
526
545
|
// eslint-disable-next-line no-underscore-dangle
|
|
527
|
-
await voiceaService._emit('event:relay.event', {
|
|
546
|
+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
528
547
|
headers: {from: 'ws'},
|
|
529
|
-
voiceaPayload
|
|
530
|
-
data: {relayType: 'voicea.transcription'}
|
|
548
|
+
data: {relayType: 'voicea.transcription', voiceaPayload}
|
|
531
549
|
});
|
|
532
550
|
|
|
533
551
|
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
|
|
552
|
+
|
|
534
553
|
assert.calledOnceWithExactly(triggerSpy, {
|
|
535
554
|
isListening: false
|
|
536
555
|
});
|
|
@@ -538,7 +557,6 @@ describe('plugin-voicea', () => {
|
|
|
538
557
|
|
|
539
558
|
it('processes a highlight', async () => {
|
|
540
559
|
voiceaService.on(EVENT_TRIGGERS.HIGHLIGHT_CREATED, triggerSpy);
|
|
541
|
-
|
|
542
560
|
const voiceaPayload = {
|
|
543
561
|
audio_received_millis: 0,
|
|
544
562
|
command_response: '',
|
|
@@ -560,10 +578,9 @@ describe('plugin-voicea', () => {
|
|
|
560
578
|
};
|
|
561
579
|
|
|
562
580
|
// eslint-disable-next-line no-underscore-dangle
|
|
563
|
-
await voiceaService._emit('event:relay.event', {
|
|
581
|
+
await voiceaService.webex.internal.llm._emit('event:relay.event', {
|
|
564
582
|
headers: {from: 'ws'},
|
|
565
|
-
voiceaPayload
|
|
566
|
-
data: {relayType: 'voicea.transcription'}
|
|
583
|
+
data: {relayType: 'voicea.transcription', voiceaPayload}
|
|
567
584
|
});
|
|
568
585
|
|
|
569
586
|
assert.calledOnceWithExactly(functionSpy, voiceaPayload);
|
|
@@ -573,7 +590,7 @@ describe('plugin-voicea', () => {
|
|
|
573
590
|
text: 'Create a decision to move ahead with the last proposal.',
|
|
574
591
|
highlightLabel: 'Decision',
|
|
575
592
|
highlightSource: 'voice-command',
|
|
576
|
-
timestamp: '
|
|
593
|
+
timestamp: '11:00'
|
|
577
594
|
});
|
|
578
595
|
});
|
|
579
596
|
});
|