@webex/internal-plugin-voicea 3.0.0-beta.17 → 3.0.0-beta.170
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 +13 -1
- package/dist/constants.js.map +1 -1
- package/dist/voicea.js +95 -38
- package/dist/voicea.js.map +1 -1
- package/dist/voicea.types.js.map +1 -1
- package/package.json +9 -9
- package/src/constants.ts +12 -0
- package/src/voicea.ts +111 -26
- package/src/voicea.types.ts +2 -2
- package/test/unit/spec/voicea.js +145 -14
package/dist/constants.js
CHANGED
|
@@ -4,7 +4,7 @@ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/defi
|
|
|
4
4
|
_Object$defineProperty(exports, "__esModule", {
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
|
-
exports.VOICEA_RELAY_TYPES = exports.VOICEA = exports.TRANSCRIPTION_TYPE = exports.EVENT_TRIGGERS = void 0;
|
|
7
|
+
exports.VOICEA_RELAY_TYPES = exports.VOICEA = exports.TURN_ON_CAPTION_STATUS = exports.TRANSCRIPTION_TYPE = exports.EVENT_TRIGGERS = exports.ANNOUNCE_STATUS = void 0;
|
|
8
8
|
var EVENT_TRIGGERS = {
|
|
9
9
|
VOICEA_ANNOUNCEMENT: 'voicea:announcement',
|
|
10
10
|
CAPTION_LANGUAGE_UPDATE: 'voicea:captionLanguageUpdate',
|
|
@@ -37,4 +37,16 @@ var TRANSCRIPTION_TYPE = {
|
|
|
37
37
|
exports.TRANSCRIPTION_TYPE = TRANSCRIPTION_TYPE;
|
|
38
38
|
var VOICEA = 'voicea';
|
|
39
39
|
exports.VOICEA = VOICEA;
|
|
40
|
+
var ANNOUNCE_STATUS = {
|
|
41
|
+
IDLE: 'idle',
|
|
42
|
+
JOINED: 'joined',
|
|
43
|
+
JOINING: 'joining'
|
|
44
|
+
};
|
|
45
|
+
exports.ANNOUNCE_STATUS = ANNOUNCE_STATUS;
|
|
46
|
+
var TURN_ON_CAPTION_STATUS = {
|
|
47
|
+
IDLE: 'idle',
|
|
48
|
+
ENABLED: 'enabled',
|
|
49
|
+
SENDING: 'sending'
|
|
50
|
+
};
|
|
51
|
+
exports.TURN_ON_CAPTION_STATUS = TURN_ON_CAPTION_STATUS;
|
|
40
52
|
//# 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","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,qBAAqB;EAC1CC,uBAAuB,EAAE,8BAA8B;EACvDC,sBAAsB,EAAE,6BAA6B;EACrDC,kBAAkB,EAAE,kBAAkB;EACtCC,eAAe,EAAE,uBAAuB;EACxCC,gBAAgB,EAAE,wBAAwB;EAE1CC,WAAW,EAAE,mBAAmB;EAChCC,WAAW,EAAE,YAAY;EACzBC,iBAAiB,EAAE;AACrB,CAAC;AAAC;AAEK,IAAMC,kBAAkB,GAAG;EAChCC,YAAY,EAAE,aAAa;EAC3BC,mBAAmB,EAAE,aAAa;EAClCC,mBAAmB,EAAE,mBAAmB;EACxCC,oBAAoB,EAAE,mBAAmB;EACzCC,aAAa,EAAE;AACjB,CAAC;AAAC;AAEK,IAAMC,kBAAkB,GAAG;EAChCC,OAAO,EAAE,SAAS;EAClBC,QAAQ,EAAE,UAAU;EACpBC,UAAU,EAAE,YAAY;EACxBC,UAAU,EAAE,YAAY;EACxBX,iBAAiB,EAAE,mBAAmB;EACtCY,0BAA0B,EAAE,4BAA4B;EACxDC,uBAAuB,EAAE;AAC3B,CAAC;AAAC;AAEK,IAAMC,MAAM,GAAG,QAAQ;AAAC"}
|
|
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","ANNOUNCE_STATUS","IDLE","JOINED","JOINING","TURN_ON_CAPTION_STATUS","ENABLED","SENDING"],"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\nexport const ANNOUNCE_STATUS = {\n IDLE: 'idle',\n JOINED: 'joined',\n JOINING: 'joining',\n};\n\nexport const TURN_ON_CAPTION_STATUS = {\n IDLE: 'idle',\n ENABLED: 'enabled',\n SENDING: 'sending',\n};\n"],"mappings":";;;;;;;AAAO,IAAMA,cAAc,GAAG;EAC5BC,mBAAmB,EAAE,qBAAqB;EAC1CC,uBAAuB,EAAE,8BAA8B;EACvDC,sBAAsB,EAAE,6BAA6B;EACrDC,kBAAkB,EAAE,kBAAkB;EACtCC,eAAe,EAAE,uBAAuB;EACxCC,gBAAgB,EAAE,wBAAwB;EAE1CC,WAAW,EAAE,mBAAmB;EAChCC,WAAW,EAAE,YAAY;EACzBC,iBAAiB,EAAE;AACrB,CAAC;AAAC;AAEK,IAAMC,kBAAkB,GAAG;EAChCC,YAAY,EAAE,aAAa;EAC3BC,mBAAmB,EAAE,aAAa;EAClCC,mBAAmB,EAAE,mBAAmB;EACxCC,oBAAoB,EAAE,mBAAmB;EACzCC,aAAa,EAAE;AACjB,CAAC;AAAC;AAEK,IAAMC,kBAAkB,GAAG;EAChCC,OAAO,EAAE,SAAS;EAClBC,QAAQ,EAAE,UAAU;EACpBC,UAAU,EAAE,YAAY;EACxBC,UAAU,EAAE,YAAY;EACxBX,iBAAiB,EAAE,mBAAmB;EACtCY,0BAA0B,EAAE,4BAA4B;EACxDC,uBAAuB,EAAE;AAC3B,CAAC;AAAC;AAEK,IAAMC,MAAM,GAAG,QAAQ;AAAC;AAExB,IAAMC,eAAe,GAAG;EAC7BC,IAAI,EAAE,MAAM;EACZC,MAAM,EAAE,QAAQ;EAChBC,OAAO,EAAE;AACX,CAAC;AAAC;AAEK,IAAMC,sBAAsB,GAAG;EACpCH,IAAI,EAAE,MAAM;EACZI,OAAO,EAAE,SAAS;EAClBC,OAAO,EAAE;AACX,CAAC;AAAC"}
|
package/dist/voicea.js
CHANGED
|
@@ -44,16 +44,17 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
44
44
|
_this = _super.call.apply(_super, [this].concat(args));
|
|
45
45
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "namespace", _constants.VOICEA);
|
|
46
46
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "seqNum", void 0);
|
|
47
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "hasVoiceaJoined", void 0);
|
|
48
47
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "areCaptionsEnabled", void 0);
|
|
49
48
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "hasSubscribedToEvents", false);
|
|
50
49
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "vmcDeviceId", void 0);
|
|
50
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "announceStatus", void 0);
|
|
51
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "captionStatus", void 0);
|
|
51
52
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "eventProcessor", function (e) {
|
|
52
53
|
_this.seqNum = e.sequenceNumber + 1;
|
|
53
54
|
switch (e.data.relayType) {
|
|
54
55
|
case _constants.VOICEA_RELAY_TYPES.ANNOUNCEMENT:
|
|
55
56
|
_this.vmcDeviceId = e.headers.from;
|
|
56
|
-
_this.
|
|
57
|
+
_this.announceStatus = _constants.ANNOUNCE_STATUS.JOINED;
|
|
57
58
|
_this.processAnnouncementMessage(e.data.voiceaPayload);
|
|
58
59
|
break;
|
|
59
60
|
case _constants.VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:
|
|
@@ -159,12 +160,14 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
159
160
|
}, _constants.EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, voiceaLanguageOptions);
|
|
160
161
|
});
|
|
161
162
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sendAnnouncement", function () {
|
|
162
|
-
|
|
163
|
+
_this.announceStatus = _constants.ANNOUNCE_STATUS.JOINING;
|
|
163
164
|
_this.listenToEvents();
|
|
165
|
+
// @ts-ignore
|
|
164
166
|
_this.webex.internal.llm.socket.send({
|
|
165
167
|
id: "".concat(_this.seqNum),
|
|
166
168
|
type: 'publishRequest',
|
|
167
169
|
recipients: {
|
|
170
|
+
// @ts-ignore
|
|
168
171
|
route: _this.webex.internal.llm.getBinding()
|
|
169
172
|
},
|
|
170
173
|
headers: {},
|
|
@@ -180,27 +183,34 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
180
183
|
_this.seqNum += 1;
|
|
181
184
|
});
|
|
182
185
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "setSpokenLanguage", function (languageCode) {
|
|
183
|
-
return
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
186
|
+
return (
|
|
187
|
+
// @ts-ignore
|
|
188
|
+
_this.request({
|
|
189
|
+
method: 'PUT',
|
|
190
|
+
// @ts-ignore
|
|
191
|
+
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
192
|
+
body: {
|
|
193
|
+
languageCode: languageCode
|
|
194
|
+
}
|
|
195
|
+
}).then(function () {
|
|
196
|
+
_pluginMeetings.TriggerProxy.trigger((0, _assertThisInitialized2.default)(_this), {
|
|
197
|
+
file: 'voicea',
|
|
198
|
+
function: 'setSpokenLanguage'
|
|
199
|
+
}, _constants.EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE, {
|
|
200
|
+
languageCode: languageCode
|
|
201
|
+
});
|
|
202
|
+
})
|
|
203
|
+
);
|
|
197
204
|
});
|
|
198
205
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "requestLanguage", function (languageCode) {
|
|
206
|
+
// @ts-ignore
|
|
199
207
|
if (!_this.webex.internal.llm.isConnected()) return;
|
|
208
|
+
// @ts-ignore
|
|
200
209
|
_this.webex.internal.llm.socket.send({
|
|
201
210
|
id: "".concat(_this.seqNum),
|
|
202
211
|
type: 'publishRequest',
|
|
203
212
|
recipients: {
|
|
213
|
+
// @ts-ignore
|
|
204
214
|
route: _this.webex.internal.llm.getBinding()
|
|
205
215
|
},
|
|
206
216
|
headers: {
|
|
@@ -218,33 +228,64 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
218
228
|
});
|
|
219
229
|
_this.seqNum += 1;
|
|
220
230
|
});
|
|
231
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "requestTurnOnCaptions", function () {
|
|
232
|
+
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.SENDING;
|
|
233
|
+
// @ts-ignore
|
|
234
|
+
// eslint-disable-next-line newline-before-return
|
|
235
|
+
return _this.request({
|
|
236
|
+
method: 'PUT',
|
|
237
|
+
// @ts-ignore
|
|
238
|
+
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
239
|
+
body: {
|
|
240
|
+
transcribe: {
|
|
241
|
+
caption: true
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}).then(function () {
|
|
245
|
+
_pluginMeetings.TriggerProxy.trigger((0, _assertThisInitialized2.default)(_this), {
|
|
246
|
+
file: 'voicea',
|
|
247
|
+
function: 'turnOnCaptions'
|
|
248
|
+
}, _constants.EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
|
|
249
|
+
_this.areCaptionsEnabled = true;
|
|
250
|
+
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.ENABLED;
|
|
251
|
+
_this.announce();
|
|
252
|
+
}).catch(function () {
|
|
253
|
+
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
|
|
254
|
+
throw new Error('turn on captions fail');
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isAnnounceProcessing", function () {
|
|
258
|
+
return [_constants.ANNOUNCE_STATUS.JOINING, _constants.ANNOUNCE_STATUS.JOINED].includes(_this.announceStatus);
|
|
259
|
+
});
|
|
260
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "announce", function () {
|
|
261
|
+
if (_this.isAnnounceProcessing()) return;
|
|
262
|
+
// @ts-ignore
|
|
263
|
+
if (!_this.webex.internal.llm.isConnected()) {
|
|
264
|
+
throw new Error('voicea can not announce before llm connected');
|
|
265
|
+
}
|
|
266
|
+
_this.sendAnnouncement();
|
|
267
|
+
});
|
|
268
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isCaptionProcessing", function () {
|
|
269
|
+
return [_constants.TURN_ON_CAPTION_STATUS.SENDING, _constants.TURN_ON_CAPTION_STATUS.ENABLED].includes(_this.captionStatus);
|
|
270
|
+
});
|
|
221
271
|
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "turnOnCaptions", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
222
272
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
223
273
|
while (1) switch (_context.prev = _context.next) {
|
|
224
274
|
case 0:
|
|
225
|
-
if (!
|
|
275
|
+
if (!_this.isCaptionProcessing()) {
|
|
226
276
|
_context.next = 2;
|
|
227
277
|
break;
|
|
228
278
|
}
|
|
229
279
|
return _context.abrupt("return", undefined);
|
|
230
280
|
case 2:
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
}).then(function () {
|
|
240
|
-
_pluginMeetings.TriggerProxy.trigger((0, _assertThisInitialized2.default)(_this), {
|
|
241
|
-
file: 'voicea',
|
|
242
|
-
function: 'turnOnCaptions'
|
|
243
|
-
}, _constants.EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
|
|
244
|
-
_this.areCaptionsEnabled = true;
|
|
245
|
-
_this.sendAnnouncement();
|
|
246
|
-
}));
|
|
247
|
-
case 3:
|
|
281
|
+
if (_this.webex.internal.llm.isConnected()) {
|
|
282
|
+
_context.next = 4;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
throw new Error('can not turn on captions before llm connected');
|
|
286
|
+
case 4:
|
|
287
|
+
return _context.abrupt("return", _this.requestTurnOnCaptions());
|
|
288
|
+
case 5:
|
|
248
289
|
case "end":
|
|
249
290
|
return _context.stop();
|
|
250
291
|
}
|
|
@@ -257,6 +298,7 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
257
298
|
case 0:
|
|
258
299
|
return _context2.abrupt("return", _this.request({
|
|
259
300
|
method: 'PUT',
|
|
301
|
+
// @ts-ignore
|
|
260
302
|
url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
|
|
261
303
|
body: {
|
|
262
304
|
transcribe: {
|
|
@@ -264,7 +306,7 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
264
306
|
}
|
|
265
307
|
}
|
|
266
308
|
}).then(function () {
|
|
267
|
-
if (activate && !_this.areCaptionsEnabled
|
|
309
|
+
if (activate && !_this.areCaptionsEnabled) _this.turnOnCaptions();
|
|
268
310
|
}));
|
|
269
311
|
case 1:
|
|
270
312
|
case "end":
|
|
@@ -276,10 +318,17 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
276
318
|
return _ref2.apply(this, arguments);
|
|
277
319
|
};
|
|
278
320
|
}());
|
|
321
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getCaptionStatus", function () {
|
|
322
|
+
return _this.captionStatus;
|
|
323
|
+
});
|
|
324
|
+
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getAnnounceStatus", function () {
|
|
325
|
+
return _this.announceStatus;
|
|
326
|
+
});
|
|
279
327
|
_this.seqNum = 1;
|
|
280
|
-
_this.hasVoiceaJoined = false;
|
|
281
328
|
_this.areCaptionsEnabled = false;
|
|
282
329
|
_this.vmcDeviceId = undefined;
|
|
330
|
+
_this.announceStatus = _constants.ANNOUNCE_STATUS.IDLE;
|
|
331
|
+
_this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
|
|
283
332
|
return _this;
|
|
284
333
|
}
|
|
285
334
|
|
|
@@ -302,18 +351,26 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
|
|
|
302
351
|
*/
|
|
303
352
|
function listenToEvents() {
|
|
304
353
|
if (!this.hasSubscribedToEvents) {
|
|
354
|
+
// @ts-ignore
|
|
305
355
|
this.webex.internal.llm.on('event:relay.event', this.eventProcessor);
|
|
306
356
|
this.hasSubscribedToEvents = true;
|
|
307
357
|
}
|
|
308
358
|
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Listen to websocket messages
|
|
362
|
+
* @returns {void}
|
|
363
|
+
*/
|
|
309
364
|
}, {
|
|
310
365
|
key: "deregisterEvents",
|
|
311
366
|
value: function deregisterEvents() {
|
|
312
|
-
this.hasVoiceaJoined = false;
|
|
313
367
|
this.areCaptionsEnabled = false;
|
|
314
368
|
this.vmcDeviceId = undefined;
|
|
369
|
+
// @ts-ignore
|
|
315
370
|
this.webex.internal.llm.off('event:relay.event', this.eventProcessor);
|
|
316
371
|
this.hasSubscribedToEvents = false;
|
|
372
|
+
this.announceStatus = _constants.ANNOUNCE_STATUS.IDLE;
|
|
373
|
+
this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
|
|
317
374
|
}
|
|
318
375
|
}]);
|
|
319
376
|
return VoiceaChannel;
|
package/dist/voicea.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["VoiceaChannel","args","VOICEA","e","seqNum","sequenceNumber","data","relayType","VOICEA_RELAY_TYPES","ANNOUNCEMENT","vmcDeviceId","headers","from","hasVoiceaJoined","processAnnouncementMessage","voiceaPayload","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","type","TRANSCRIPTION_TYPE","TRANSCRIPT_INTERIM_RESULTS","Trigger","trigger","file","function","EVENT_TRIGGERS","NEW_CAPTION","isFinal","transcriptId","transcript_id","transcripts","TRANSCRIPT_FINAL_RESULT","transcript","csis","text","transcriptLanguageCode","transcript_language_code","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","webex","internal","llm","isConnected","listenToEvents","socket","send","id","recipients","route","getBinding","clientPayload","version","eventType","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","languageCode","request","method","url","getLocusUrl","body","then","SPOKEN_LANGUAGE_UPDATE","to","translationLanguage","TRANSLATION_REQUEST","areCaptionsEnabled","undefined","transcribe","caption","CAPTIONS_TURNED_ON","sendAnnouncement","activate","transcribing","turnOnCaptions","hasSubscribedToEvents","on","eventProcessor","off","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 {\n AnnouncementPayload,\n CaptionLanguageResponse,\n TranscriptionResponse,\n IVoiceaChannel,\n} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * @description VoiceaChannel to hold single instance of LLM\n * @export\n * @class VoiceaChannel\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 hasSubscribedToEvents = false;\n\n private vmcDeviceId?: string;\n\n /**\n * @param {Object} e\n * @returns {undefined}\n */\n\n private eventProcessor = (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 * Listen to websocket messages\n * @returns {undefined}\n */\n private listenToEvents() {\n if (!this.hasSubscribedToEvents) {\n this.webex.internal.llm.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n }\n }\n\n public deregisterEvents() {\n this.hasVoiceaJoined = false;\n this.areCaptionsEnabled = false;\n this.vmcDeviceId = undefined;\n this.webex.internal.llm.off('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = false;\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.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(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.NEW_CAPTION,\n {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts,\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.NEW_CAPTION,\n {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\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 );\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.HIGHLIGHT_CREATED,\n {\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 );\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.EVA_COMMAND,\n {\n isListening: false,\n text: voiceaPayload.command_response,\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.EVA_COMMAND,\n {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE,\n }\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(\n this,\n {\n file: 'voicea',\n function: 'processCaptionLanguageResponse',\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,\n {statusCode: 200}\n );\n } else {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processCaptionLanguageResponse',\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,\n {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message}\n );\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 * 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\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> =>\n this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n languageCode,\n },\n }).then(() => {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'setSpokenLanguage',\n },\n EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,\n {languageCode}\n );\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(\n this,\n {\n file: 'voicea',\n function: 'turnOnCaptions',\n },\n EVENT_TRIGGERS.CAPTIONS_TURNED_ON\n );\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 return this.request({\n method: 'PUT',\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {transcribing: activate},\n },\n }).then(() => {\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","e","seqNum","sequenceNumber","data","relayType","VOICEA_RELAY_TYPES","ANNOUNCEMENT","vmcDeviceId","headers","from","announceStatus","ANNOUNCE_STATUS","JOINED","processAnnouncementMessage","voiceaPayload","TRANSLATION_RESPONSE","processCaptionLanguageResponse","TRANSCRIPTION","processTranscription","type","TRANSCRIPTION_TYPE","TRANSCRIPT_INTERIM_RESULTS","Trigger","trigger","file","function","EVENT_TRIGGERS","NEW_CAPTION","isFinal","transcriptId","transcript_id","transcripts","TRANSCRIPT_FINAL_RESULT","transcript","csis","text","transcriptLanguageCode","transcript_language_code","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","JOINING","listenToEvents","webex","internal","llm","socket","send","id","recipients","route","getBinding","clientPayload","version","eventType","CLIENT_ANNOUNCEMENT","trackingId","config","trackingIdPrefix","uuid","v4","toString","languageCode","request","method","url","getLocusUrl","body","then","SPOKEN_LANGUAGE_UPDATE","isConnected","to","translationLanguage","TRANSLATION_REQUEST","captionStatus","TURN_ON_CAPTION_STATUS","SENDING","transcribe","caption","CAPTIONS_TURNED_ON","areCaptionsEnabled","ENABLED","announce","catch","IDLE","Error","includes","isAnnounceProcessing","sendAnnouncement","isCaptionProcessing","undefined","requestTurnOnCaptions","activate","transcribing","turnOnCaptions","hasSubscribedToEvents","on","eventProcessor","off","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 {\n EVENT_TRIGGERS,\n VOICEA_RELAY_TYPES,\n TRANSCRIPTION_TYPE,\n VOICEA,\n ANNOUNCE_STATUS,\n TURN_ON_CAPTION_STATUS,\n} from './constants';\n// eslint-disable-next-line no-unused-vars\nimport {\n AnnouncementPayload,\n CaptionLanguageResponse,\n TranscriptionResponse,\n IVoiceaChannel,\n} from './voicea.types';\nimport {millisToMinutesAndSeconds} from './utils';\n\n/**\n * @description VoiceaChannel to hold single instance of LLM\n * @export\n * @class VoiceaChannel\n */\nexport class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {\n namespace = VOICEA;\n\n private seqNum: number;\n\n private areCaptionsEnabled: boolean;\n\n private hasSubscribedToEvents = false;\n\n private vmcDeviceId?: string;\n\n private announceStatus: string;\n\n private captionStatus: string;\n\n /**\n * @param {Object} e\n * @returns {undefined}\n */\n\n private eventProcessor = (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.announceStatus = ANNOUNCE_STATUS.JOINED;\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 * Listen to websocket messages\n * @returns {undefined}\n */\n private listenToEvents() {\n if (!this.hasSubscribedToEvents) {\n // @ts-ignore\n this.webex.internal.llm.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n }\n }\n\n /**\n * Listen to websocket messages\n * @returns {void}\n */\n public deregisterEvents() {\n this.areCaptionsEnabled = false;\n this.vmcDeviceId = undefined;\n // @ts-ignore\n this.webex.internal.llm.off('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = false;\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n }\n\n /**\n * Initializes Voicea plugin\n * @param {any} args\n */\n constructor(...args) {\n super(...args);\n this.seqNum = 1;\n this.areCaptionsEnabled = false;\n this.vmcDeviceId = undefined;\n this.announceStatus = ANNOUNCE_STATUS.IDLE;\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\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(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.NEW_CAPTION,\n {\n isFinal: false,\n transcriptId: voiceaPayload.transcript_id,\n transcripts: voiceaPayload.transcripts,\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.TRANSCRIPT_FINAL_RESULT:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.NEW_CAPTION,\n {\n isFinal: true,\n transcriptId: voiceaPayload.transcript_id,\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 );\n break;\n\n case TRANSCRIPTION_TYPE.HIGHLIGHT_CREATED:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.HIGHLIGHT_CREATED,\n {\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 );\n break;\n\n case TRANSCRIPTION_TYPE.EVA_THANKS:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.EVA_COMMAND,\n {\n isListening: false,\n text: voiceaPayload.command_response,\n }\n );\n break;\n\n case TRANSCRIPTION_TYPE.EVA_WAKE:\n case TRANSCRIPTION_TYPE.EVA_CANCEL:\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processTranscription',\n },\n EVENT_TRIGGERS.EVA_COMMAND,\n {\n isListening: voiceaPayload.type === TRANSCRIPTION_TYPE.EVA_WAKE,\n }\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(\n this,\n {\n file: 'voicea',\n function: 'processCaptionLanguageResponse',\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,\n {statusCode: 200}\n );\n } else {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'processCaptionLanguageResponse',\n },\n EVENT_TRIGGERS.CAPTION_LANGUAGE_UPDATE,\n {statusCode: voiceaPayload.errorCode, errorMessage: voiceaPayload.message}\n );\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 * Sends Announcement to add voicea to the meeting\n * @returns {void}\n */\n private sendAnnouncement = (): void => {\n this.announceStatus = ANNOUNCE_STATUS.JOINING;\n this.listenToEvents();\n // @ts-ignore\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n // @ts-ignore\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> =>\n // @ts-ignore\n this.request({\n method: 'PUT',\n // @ts-ignore\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n languageCode,\n },\n }).then(() => {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'setSpokenLanguage',\n },\n EVENT_TRIGGERS.SPOKEN_LANGUAGE_UPDATE,\n {languageCode}\n );\n });\n\n /**\n * Request Language translation\n * @param {string} languageCode\n * @returns {void}\n */\n public requestLanguage = (languageCode: string): void => {\n // @ts-ignore\n if (!this.webex.internal.llm.isConnected()) return;\n // @ts-ignore\n this.webex.internal.llm.socket.send({\n id: `${this.seqNum}`,\n type: 'publishRequest',\n recipients: {\n // @ts-ignore\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 * request turn on Captions\n * @returns {Promise}\n */\n private requestTurnOnCaptions = (): undefined | Promise<void> => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;\n // @ts-ignore\n // eslint-disable-next-line newline-before-return\n return this.request({\n method: 'PUT',\n // @ts-ignore\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {caption: true},\n },\n })\n .then(() => {\n Trigger.trigger(\n this,\n {\n file: 'voicea',\n function: 'turnOnCaptions',\n },\n EVENT_TRIGGERS.CAPTIONS_TURNED_ON\n );\n this.areCaptionsEnabled = true;\n this.captionStatus = TURN_ON_CAPTION_STATUS.ENABLED;\n this.announce();\n })\n .catch(() => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;\n throw new Error('turn on captions fail');\n });\n };\n\n /**\n * is announce processing\n * @returns {boolean}\n */\n private isAnnounceProcessing = () =>\n [ANNOUNCE_STATUS.JOINING, ANNOUNCE_STATUS.JOINED].includes(this.announceStatus);\n\n /**\n * announce to voicea data chanel\n * @returns {void}\n */\n public announce = () => {\n if (this.isAnnounceProcessing()) return;\n // @ts-ignore\n if (!this.webex.internal.llm.isConnected()) {\n throw new Error('voicea can not announce before llm connected');\n }\n this.sendAnnouncement();\n };\n\n /**\n * is turn on caption processing\n * @returns {boolean}\n */\n private isCaptionProcessing = () =>\n [TURN_ON_CAPTION_STATUS.SENDING, TURN_ON_CAPTION_STATUS.ENABLED].includes(this.captionStatus);\n\n /**\n * Turn on Captions\n * @returns {Promise}\n */\n public turnOnCaptions = async (): undefined | Promise<void> => {\n if (this.isCaptionProcessing()) return undefined;\n // @ts-ignore\n if (!this.webex.internal.llm.isConnected()) {\n throw new Error('can not turn on captions before llm connected');\n }\n\n return this.requestTurnOnCaptions();\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 // @ts-ignore\n return this.request({\n method: 'PUT',\n // @ts-ignore\n url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,\n body: {\n transcribe: {transcribing: activate},\n },\n }).then(() => {\n if (activate && !this.areCaptionsEnabled) this.turnOnCaptions();\n });\n };\n\n /**\n * get caption status\n * @returns {string}\n */\n public getCaptionStatus = () => this.captionStatus;\n\n /**\n * get announce status\n * @returns {string}\n */\n public getAnnounceStatus = () => this.announceStatus;\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 =\n | '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 */\ninterface 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 deregisterEvents: () =>
|
|
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 =\n | '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 */\ninterface 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 deregisterEvents: () => void;\n}\n\nexport type {\n AnnouncementPayload,\n CaptionLanguageResponse,\n TranscriptionResponse,\n Transcription,\n Highlight,\n IVoiceaChannel,\n};\n"],"mappings":""}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-voicea",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.170",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
"node": ">=16"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@webex/internal-plugin-llm": "3.0.0-beta.
|
|
18
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
19
|
-
"@webex/internal-plugin-voicea": "3.0.0-beta.
|
|
20
|
-
"@webex/plugin-meetings": "3.0.0-beta.
|
|
21
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
17
|
+
"@webex/internal-plugin-llm": "3.0.0-beta.170",
|
|
18
|
+
"@webex/internal-plugin-mercury": "3.0.0-beta.170",
|
|
19
|
+
"@webex/internal-plugin-voicea": "3.0.0-beta.170",
|
|
20
|
+
"@webex/plugin-meetings": "3.0.0-beta.170",
|
|
21
|
+
"@webex/webex-core": "3.0.0-beta.170",
|
|
22
22
|
"uuid": "^3.3.2"
|
|
23
23
|
},
|
|
24
24
|
"browserify": {
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
]
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
32
|
-
"@webex/test-helper-mock-web-socket": "3.0.0-beta.
|
|
33
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
31
|
+
"@webex/test-helper-chai": "3.0.0-beta.170",
|
|
32
|
+
"@webex/test-helper-mock-web-socket": "3.0.0-beta.170",
|
|
33
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.170",
|
|
34
34
|
"sinon": "^9.2.4"
|
|
35
35
|
}
|
|
36
36
|
}
|
package/src/constants.ts
CHANGED
|
@@ -30,3 +30,15 @@ export const TRANSCRIPTION_TYPE = {
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
export const VOICEA = 'voicea';
|
|
33
|
+
|
|
34
|
+
export const ANNOUNCE_STATUS = {
|
|
35
|
+
IDLE: 'idle',
|
|
36
|
+
JOINED: 'joined',
|
|
37
|
+
JOINING: 'joining',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const TURN_ON_CAPTION_STATUS = {
|
|
41
|
+
IDLE: 'idle',
|
|
42
|
+
ENABLED: 'enabled',
|
|
43
|
+
SENDING: 'sending',
|
|
44
|
+
};
|
package/src/voicea.ts
CHANGED
|
@@ -2,7 +2,14 @@ import uuid from 'uuid';
|
|
|
2
2
|
import {TriggerProxy as Trigger} from '@webex/plugin-meetings';
|
|
3
3
|
import {WebexPlugin, config} from '@webex/webex-core';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
EVENT_TRIGGERS,
|
|
7
|
+
VOICEA_RELAY_TYPES,
|
|
8
|
+
TRANSCRIPTION_TYPE,
|
|
9
|
+
VOICEA,
|
|
10
|
+
ANNOUNCE_STATUS,
|
|
11
|
+
TURN_ON_CAPTION_STATUS,
|
|
12
|
+
} from './constants';
|
|
6
13
|
// eslint-disable-next-line no-unused-vars
|
|
7
14
|
import {
|
|
8
15
|
AnnouncementPayload,
|
|
@@ -22,14 +29,16 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
22
29
|
|
|
23
30
|
private seqNum: number;
|
|
24
31
|
|
|
25
|
-
private hasVoiceaJoined: boolean;
|
|
26
|
-
|
|
27
32
|
private areCaptionsEnabled: boolean;
|
|
28
33
|
|
|
29
34
|
private hasSubscribedToEvents = false;
|
|
30
35
|
|
|
31
36
|
private vmcDeviceId?: string;
|
|
32
37
|
|
|
38
|
+
private announceStatus: string;
|
|
39
|
+
|
|
40
|
+
private captionStatus: string;
|
|
41
|
+
|
|
33
42
|
/**
|
|
34
43
|
* @param {Object} e
|
|
35
44
|
* @returns {undefined}
|
|
@@ -40,7 +49,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
40
49
|
switch (e.data.relayType) {
|
|
41
50
|
case VOICEA_RELAY_TYPES.ANNOUNCEMENT:
|
|
42
51
|
this.vmcDeviceId = e.headers.from;
|
|
43
|
-
this.
|
|
52
|
+
this.announceStatus = ANNOUNCE_STATUS.JOINED;
|
|
44
53
|
this.processAnnouncementMessage(e.data.voiceaPayload);
|
|
45
54
|
break;
|
|
46
55
|
case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:
|
|
@@ -60,17 +69,24 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
60
69
|
*/
|
|
61
70
|
private listenToEvents() {
|
|
62
71
|
if (!this.hasSubscribedToEvents) {
|
|
72
|
+
// @ts-ignore
|
|
63
73
|
this.webex.internal.llm.on('event:relay.event', this.eventProcessor);
|
|
64
74
|
this.hasSubscribedToEvents = true;
|
|
65
75
|
}
|
|
66
76
|
}
|
|
67
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Listen to websocket messages
|
|
80
|
+
* @returns {void}
|
|
81
|
+
*/
|
|
68
82
|
public deregisterEvents() {
|
|
69
|
-
this.hasVoiceaJoined = false;
|
|
70
83
|
this.areCaptionsEnabled = false;
|
|
71
84
|
this.vmcDeviceId = undefined;
|
|
85
|
+
// @ts-ignore
|
|
72
86
|
this.webex.internal.llm.off('event:relay.event', this.eventProcessor);
|
|
73
87
|
this.hasSubscribedToEvents = false;
|
|
88
|
+
this.announceStatus = ANNOUNCE_STATUS.IDLE;
|
|
89
|
+
this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
|
|
74
90
|
}
|
|
75
91
|
|
|
76
92
|
/**
|
|
@@ -80,9 +96,10 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
80
96
|
constructor(...args) {
|
|
81
97
|
super(...args);
|
|
82
98
|
this.seqNum = 1;
|
|
83
|
-
this.hasVoiceaJoined = false;
|
|
84
99
|
this.areCaptionsEnabled = false;
|
|
85
100
|
this.vmcDeviceId = undefined;
|
|
101
|
+
this.announceStatus = ANNOUNCE_STATUS.IDLE;
|
|
102
|
+
this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
|
|
86
103
|
}
|
|
87
104
|
|
|
88
105
|
/**
|
|
@@ -240,14 +257,14 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
240
257
|
* @returns {void}
|
|
241
258
|
*/
|
|
242
259
|
private sendAnnouncement = (): void => {
|
|
243
|
-
|
|
244
|
-
|
|
260
|
+
this.announceStatus = ANNOUNCE_STATUS.JOINING;
|
|
245
261
|
this.listenToEvents();
|
|
246
|
-
|
|
262
|
+
// @ts-ignore
|
|
247
263
|
this.webex.internal.llm.socket.send({
|
|
248
264
|
id: `${this.seqNum}`,
|
|
249
265
|
type: 'publishRequest',
|
|
250
266
|
recipients: {
|
|
267
|
+
// @ts-ignore
|
|
251
268
|
route: this.webex.internal.llm.getBinding(),
|
|
252
269
|
},
|
|
253
270
|
headers: {},
|
|
@@ -269,8 +286,10 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
269
286
|
* @returns {Promise}
|
|
270
287
|
*/
|
|
271
288
|
public setSpokenLanguage = (languageCode: string): Promise<void> =>
|
|
289
|
+
// @ts-ignore
|
|
272
290
|
this.request({
|
|
273
291
|
method: 'PUT',
|
|
292
|
+
// @ts-ignore
|
|
274
293
|
url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
|
|
275
294
|
body: {
|
|
276
295
|
languageCode,
|
|
@@ -293,11 +312,14 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
293
312
|
* @returns {void}
|
|
294
313
|
*/
|
|
295
314
|
public requestLanguage = (languageCode: string): void => {
|
|
315
|
+
// @ts-ignore
|
|
296
316
|
if (!this.webex.internal.llm.isConnected()) return;
|
|
317
|
+
// @ts-ignore
|
|
297
318
|
this.webex.internal.llm.socket.send({
|
|
298
319
|
id: `${this.seqNum}`,
|
|
299
320
|
type: 'publishRequest',
|
|
300
321
|
recipients: {
|
|
322
|
+
// @ts-ignore
|
|
301
323
|
route: this.webex.internal.llm.getBinding(),
|
|
302
324
|
},
|
|
303
325
|
headers: {
|
|
@@ -317,30 +339,79 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
317
339
|
};
|
|
318
340
|
|
|
319
341
|
/**
|
|
320
|
-
*
|
|
342
|
+
* request turn on Captions
|
|
321
343
|
* @returns {Promise}
|
|
322
344
|
*/
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
345
|
+
private requestTurnOnCaptions = (): undefined | Promise<void> => {
|
|
346
|
+
this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
// eslint-disable-next-line newline-before-return
|
|
326
349
|
return this.request({
|
|
327
350
|
method: 'PUT',
|
|
351
|
+
// @ts-ignore
|
|
328
352
|
url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
|
|
329
353
|
body: {
|
|
330
354
|
transcribe: {caption: true},
|
|
331
355
|
},
|
|
332
|
-
})
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
356
|
+
})
|
|
357
|
+
.then(() => {
|
|
358
|
+
Trigger.trigger(
|
|
359
|
+
this,
|
|
360
|
+
{
|
|
361
|
+
file: 'voicea',
|
|
362
|
+
function: 'turnOnCaptions',
|
|
363
|
+
},
|
|
364
|
+
EVENT_TRIGGERS.CAPTIONS_TURNED_ON
|
|
365
|
+
);
|
|
366
|
+
this.areCaptionsEnabled = true;
|
|
367
|
+
this.captionStatus = TURN_ON_CAPTION_STATUS.ENABLED;
|
|
368
|
+
this.announce();
|
|
369
|
+
})
|
|
370
|
+
.catch(() => {
|
|
371
|
+
this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
|
|
372
|
+
throw new Error('turn on captions fail');
|
|
373
|
+
});
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* is announce processing
|
|
378
|
+
* @returns {boolean}
|
|
379
|
+
*/
|
|
380
|
+
private isAnnounceProcessing = () =>
|
|
381
|
+
[ANNOUNCE_STATUS.JOINING, ANNOUNCE_STATUS.JOINED].includes(this.announceStatus);
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* announce to voicea data chanel
|
|
385
|
+
* @returns {void}
|
|
386
|
+
*/
|
|
387
|
+
public announce = () => {
|
|
388
|
+
if (this.isAnnounceProcessing()) return;
|
|
389
|
+
// @ts-ignore
|
|
390
|
+
if (!this.webex.internal.llm.isConnected()) {
|
|
391
|
+
throw new Error('voicea can not announce before llm connected');
|
|
392
|
+
}
|
|
393
|
+
this.sendAnnouncement();
|
|
394
|
+
};
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* is turn on caption processing
|
|
398
|
+
* @returns {boolean}
|
|
399
|
+
*/
|
|
400
|
+
private isCaptionProcessing = () =>
|
|
401
|
+
[TURN_ON_CAPTION_STATUS.SENDING, TURN_ON_CAPTION_STATUS.ENABLED].includes(this.captionStatus);
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Turn on Captions
|
|
405
|
+
* @returns {Promise}
|
|
406
|
+
*/
|
|
407
|
+
public turnOnCaptions = async (): undefined | Promise<void> => {
|
|
408
|
+
if (this.isCaptionProcessing()) return undefined;
|
|
409
|
+
// @ts-ignore
|
|
410
|
+
if (!this.webex.internal.llm.isConnected()) {
|
|
411
|
+
throw new Error('can not turn on captions before llm connected');
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return this.requestTurnOnCaptions();
|
|
344
415
|
};
|
|
345
416
|
|
|
346
417
|
/**
|
|
@@ -349,16 +420,30 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
|
|
|
349
420
|
* @returns {Promise}
|
|
350
421
|
*/
|
|
351
422
|
public toggleTranscribing = async (activate: boolean): undefined | Promise<void> => {
|
|
423
|
+
// @ts-ignore
|
|
352
424
|
return this.request({
|
|
353
425
|
method: 'PUT',
|
|
426
|
+
// @ts-ignore
|
|
354
427
|
url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
|
|
355
428
|
body: {
|
|
356
429
|
transcribe: {transcribing: activate},
|
|
357
430
|
},
|
|
358
431
|
}).then(() => {
|
|
359
|
-
if (activate && !this.areCaptionsEnabled
|
|
432
|
+
if (activate && !this.areCaptionsEnabled) this.turnOnCaptions();
|
|
360
433
|
});
|
|
361
434
|
};
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* get caption status
|
|
438
|
+
* @returns {string}
|
|
439
|
+
*/
|
|
440
|
+
public getCaptionStatus = () => this.captionStatus;
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* get announce status
|
|
444
|
+
* @returns {string}
|
|
445
|
+
*/
|
|
446
|
+
public getAnnounceStatus = () => this.announceStatus;
|
|
362
447
|
}
|
|
363
448
|
|
|
364
449
|
export default VoiceaChannel;
|
package/src/voicea.types.ts
CHANGED
|
@@ -79,10 +79,10 @@ interface IVoiceaChannel {
|
|
|
79
79
|
requestLanguage: (languageCode: string) => void;
|
|
80
80
|
turnOnCaptions: () => undefined | Promise<void>;
|
|
81
81
|
toggleTranscribing: (activate: boolean) => undefined | Promise<void>;
|
|
82
|
-
deregisterEvents: () =>
|
|
82
|
+
deregisterEvents: () => void;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
export {
|
|
85
|
+
export type {
|
|
86
86
|
AnnouncementPayload,
|
|
87
87
|
CaptionLanguageResponse,
|
|
88
88
|
TranscriptionResponse,
|
package/test/unit/spec/voicea.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
1
2
|
import MockWebex from '@webex/test-helper-mock-webex';
|
|
2
3
|
import MockWebSocket from '@webex/test-helper-mock-web-socket';
|
|
3
|
-
import {assert} from '@webex/test-helper-chai';
|
|
4
|
+
import {assert, expect} from '@webex/test-helper-chai';
|
|
4
5
|
import sinon from 'sinon';
|
|
5
6
|
import Mercury from '@webex/internal-plugin-mercury';
|
|
6
7
|
import LLMChannel from '@webex/internal-plugin-llm';
|
|
@@ -41,17 +42,26 @@ describe('plugin-voicea', () => {
|
|
|
41
42
|
});
|
|
42
43
|
});
|
|
43
44
|
|
|
45
|
+
describe("#constructor", () => {
|
|
46
|
+
it('should init status', () => {
|
|
47
|
+
assert.equal(voiceaService.announceStatus, 'idle');
|
|
48
|
+
assert.equal(voiceaService.captionStatus, 'idle');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
|
|
44
52
|
describe('#sendAnnouncement', () => {
|
|
45
53
|
beforeEach(async () => {
|
|
46
54
|
const mockWebSocket = new MockWebSocket();
|
|
47
55
|
|
|
48
56
|
voiceaService.webex.internal.llm.socket = mockWebSocket;
|
|
57
|
+
voiceaService.announceStatus = "idle";
|
|
49
58
|
});
|
|
50
59
|
|
|
51
60
|
it("sends announcement if voicea hasn't joined", () => {
|
|
52
61
|
const spy = sinon.spy(voiceaService, 'listenToEvents');
|
|
53
62
|
|
|
54
63
|
voiceaService.sendAnnouncement();
|
|
64
|
+
assert.equal(voiceaService.announceStatus, 'joining');
|
|
55
65
|
assert.calledOnce(spy);
|
|
56
66
|
|
|
57
67
|
assert.calledOnceWithExactly(voiceaService.webex.internal.llm.socket.send, {
|
|
@@ -98,14 +108,14 @@ describe('plugin-voicea', () => {
|
|
|
98
108
|
data: {relayType: 'voicea.annc', voiceaPayload: {}},
|
|
99
109
|
});
|
|
100
110
|
|
|
101
|
-
assert.equal(voiceaService.hasVoiceaJoined, true);
|
|
102
111
|
assert.equal(voiceaService.areCaptionsEnabled, true);
|
|
103
112
|
assert.equal(voiceaService.vmcDeviceId, 'ws');
|
|
104
113
|
|
|
105
114
|
voiceaService.deregisterEvents();
|
|
106
|
-
assert.equal(voiceaService.hasVoiceaJoined, false);
|
|
107
115
|
assert.equal(voiceaService.areCaptionsEnabled, false);
|
|
108
116
|
assert.equal(voiceaService.vmcDeviceId, undefined);
|
|
117
|
+
assert.equal(voiceaService.announceStatus, 'idle');
|
|
118
|
+
assert.equal(voiceaService.captionStatus, 'idle');
|
|
109
119
|
});
|
|
110
120
|
});
|
|
111
121
|
describe('#processAnnouncementMessage', () => {
|
|
@@ -198,22 +208,28 @@ describe('plugin-voicea', () => {
|
|
|
198
208
|
});
|
|
199
209
|
});
|
|
200
210
|
|
|
201
|
-
describe('#
|
|
211
|
+
describe('#requestTurnOnCaptions', () => {
|
|
202
212
|
beforeEach(async () => {
|
|
203
213
|
const mockWebSocket = new MockWebSocket();
|
|
204
214
|
|
|
205
215
|
voiceaService.webex.internal.llm.socket = mockWebSocket;
|
|
216
|
+
voiceaService.captionStatus = 'idle';
|
|
206
217
|
});
|
|
207
218
|
|
|
219
|
+
afterEach( () => {
|
|
220
|
+
voiceaService.captionStatus = 'idle';
|
|
221
|
+
})
|
|
222
|
+
|
|
208
223
|
it('turns on captions', async () => {
|
|
209
|
-
const announcementSpy = sinon.spy(voiceaService, '
|
|
224
|
+
const announcementSpy = sinon.spy(voiceaService, 'announce');
|
|
210
225
|
|
|
211
226
|
const triggerSpy = sinon.spy();
|
|
212
227
|
|
|
213
228
|
voiceaService.on(EVENT_TRIGGERS.CAPTIONS_TURNED_ON, triggerSpy);
|
|
214
229
|
voiceaService.listenToEvents();
|
|
215
230
|
|
|
216
|
-
await voiceaService.
|
|
231
|
+
await voiceaService.requestTurnOnCaptions();
|
|
232
|
+
assert.equal(voiceaService.captionStatus, 'enabled');
|
|
217
233
|
sinon.assert.calledWith(
|
|
218
234
|
voiceaService.request,
|
|
219
235
|
sinon.match({
|
|
@@ -228,18 +244,119 @@ describe('plugin-voicea', () => {
|
|
|
228
244
|
assert.calledOnce(announcementSpy);
|
|
229
245
|
});
|
|
230
246
|
|
|
231
|
-
it("
|
|
232
|
-
|
|
247
|
+
it("should handle request fail", async () => {
|
|
248
|
+
voiceaService.captionStatus = 'sending';
|
|
249
|
+
voiceaService.request = sinon.stub().rejects();
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
await voiceaService.requestTurnOnCaptions();
|
|
253
|
+
} catch (error) {
|
|
254
|
+
expect(error.message).to.include('turn on captions fail');
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
assert.equal(voiceaService.captionStatus, 'idle');
|
|
258
|
+
});
|
|
259
|
+
});
|
|
233
260
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
261
|
+
describe("#isAnnounceProcessing", () => {
|
|
262
|
+
afterEach(() => {
|
|
263
|
+
voiceaService.announceStatus = 'idle';
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
['joining', 'joined'].forEach((status) => {
|
|
267
|
+
it(`should return true when status is ${status}`, () => {
|
|
268
|
+
voiceaService.announceStatus = status;
|
|
269
|
+
assert.equal(voiceaService.isAnnounceProcessing(), true);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it('should return false when status is not processing status', () => {
|
|
274
|
+
voiceaService.announceStatus = 'idle';
|
|
275
|
+
assert.equal(voiceaService.isAnnounceProcessing(), false);
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
describe("#announce", () => {
|
|
280
|
+
let isAnnounceProcessing, sendAnnouncement;
|
|
281
|
+
beforeEach(() => {
|
|
282
|
+
voiceaService.webex.internal.llm.isConnected.returns(true);
|
|
283
|
+
sendAnnouncement = sinon.stub(voiceaService, 'sendAnnouncement');
|
|
284
|
+
isAnnounceProcessing = sinon.stub(voiceaService, 'isAnnounceProcessing').returns(false)
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
afterEach(() => {
|
|
288
|
+
voiceaService.webex.internal.llm.isConnected.returns(true);
|
|
289
|
+
isAnnounceProcessing.restore();
|
|
290
|
+
sendAnnouncement.restore();
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
it('announce to llm data channel', ()=> {
|
|
294
|
+
voiceaService.announce();
|
|
295
|
+
assert.calledOnce(sendAnnouncement);
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it('announce to llm data channel before llm connected', ()=> {
|
|
299
|
+
voiceaService.webex.internal.llm.isConnected.returns(false);
|
|
300
|
+
assert.throws(() => voiceaService.announce(), "voicea can not announce before llm connected");
|
|
301
|
+
assert.notCalled(sendAnnouncement);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('should not announce duplicate', () => {
|
|
305
|
+
isAnnounceProcessing.returns(true);
|
|
306
|
+
voiceaService.announce();
|
|
307
|
+
assert.notCalled(sendAnnouncement);
|
|
308
|
+
})
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
describe("#isCaptionProcessing", () => {
|
|
312
|
+
afterEach(() => {
|
|
313
|
+
voiceaService.captionStatus = 'idle';
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
['sending', 'enabled'].forEach((status) => {
|
|
317
|
+
it(`should return true when status is ${status}`, () => {
|
|
318
|
+
voiceaService.captionStatus = status;
|
|
319
|
+
assert.equal(voiceaService.isCaptionProcessing(), true);
|
|
238
320
|
});
|
|
321
|
+
});
|
|
239
322
|
|
|
240
|
-
|
|
323
|
+
it('should return false when status is not processing status', () => {
|
|
324
|
+
voiceaService.captionStatus = 'idle';
|
|
325
|
+
assert.equal(voiceaService.isCaptionProcessing(), false);
|
|
326
|
+
});
|
|
327
|
+
});
|
|
241
328
|
|
|
242
|
-
|
|
329
|
+
describe('#turnOnCaptions', () => {
|
|
330
|
+
let requestTurnOnCaptions, isCaptionProcessing;
|
|
331
|
+
beforeEach(() => {
|
|
332
|
+
requestTurnOnCaptions = sinon.stub(voiceaService, 'requestTurnOnCaptions');
|
|
333
|
+
isCaptionProcessing = sinon.stub(voiceaService, 'isCaptionProcessing').returns(false);
|
|
334
|
+
voiceaService.webex.internal.llm.isConnected.returns(true);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
afterEach(() => {
|
|
338
|
+
requestTurnOnCaptions.restore();
|
|
339
|
+
isCaptionProcessing.restore();
|
|
340
|
+
voiceaService.webex.internal.llm.isConnected.returns(true);
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
it('call request turn on captions', () => {
|
|
344
|
+
isCaptionProcessing.returns(false);
|
|
345
|
+
voiceaService.turnOnCaptions();
|
|
346
|
+
assert.calledOnce(requestTurnOnCaptions);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
it("turns on captions before llm connected", () => {
|
|
350
|
+
isCaptionProcessing.returns(false);
|
|
351
|
+
voiceaService.webex.internal.llm.isConnected.returns(true);
|
|
352
|
+
// assert.throws(() => voiceaService.turnOnCaptions(), "can not turn on captions before llm connected");
|
|
353
|
+
assert.notCalled(requestTurnOnCaptions);
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it('should not turn on duplicate when processing', () => {
|
|
357
|
+
isCaptionProcessing.returns(true);
|
|
358
|
+
voiceaService.turnOnCaptions();
|
|
359
|
+
assert.notCalled(voiceaService.requestTurnOnCaptions);
|
|
243
360
|
});
|
|
244
361
|
});
|
|
245
362
|
|
|
@@ -613,5 +730,19 @@ describe('plugin-voicea', () => {
|
|
|
613
730
|
});
|
|
614
731
|
});
|
|
615
732
|
});
|
|
733
|
+
|
|
734
|
+
describe("#getCaptionStatus", () => {
|
|
735
|
+
it('works correctly', () => {
|
|
736
|
+
voiceaService.captionStatus = "enabled"
|
|
737
|
+
assert.equal(voiceaService.getCaptionStatus(), "enabled");
|
|
738
|
+
});
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
describe("#getAnnounceStatus", () => {
|
|
742
|
+
it('works correctly', () => {
|
|
743
|
+
voiceaService.announceStatus = "joined"
|
|
744
|
+
assert.equal(voiceaService.getAnnounceStatus(), "joined");
|
|
745
|
+
});
|
|
746
|
+
});
|
|
616
747
|
});
|
|
617
748
|
});
|