@webex/internal-plugin-voicea 3.0.0-beta.41 → 3.0.0-beta.411

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 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
@@ -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/index.js CHANGED
@@ -8,6 +8,18 @@ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequ
8
8
  _Object$defineProperty(exports, "__esModule", {
9
9
  value: true
10
10
  });
11
+ _Object$defineProperty(exports, "EVENT_TRIGGERS", {
12
+ enumerable: true,
13
+ get: function get() {
14
+ return _constants.EVENT_TRIGGERS;
15
+ }
16
+ });
17
+ _Object$defineProperty(exports, "TURN_ON_CAPTION_STATUS", {
18
+ enumerable: true,
19
+ get: function get() {
20
+ return _constants.TURN_ON_CAPTION_STATUS;
21
+ }
22
+ });
11
23
  _Object$defineProperty(exports, "default", {
12
24
  enumerable: true,
13
25
  get: function get() {
@@ -16,6 +28,7 @@ _Object$defineProperty(exports, "default", {
16
28
  });
17
29
  var WebexCore = _interopRequireWildcard(require("@webex/webex-core"));
18
30
  var _voicea = _interopRequireDefault(require("./voicea"));
31
+ var _constants = require("./constants");
19
32
  function _getRequireWildcardCache(nodeInterop) { if (typeof _WeakMap !== "function") return null; var cacheBabelInterop = new _WeakMap(); var cacheNodeInterop = new _WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
20
33
  function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = _Object$defineProperty && _Object$getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? _Object$getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { _Object$defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
21
34
  WebexCore.registerInternalPlugin('voicea', _voicea.default, {});
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';\n\nimport VoiceaChannel from './voicea';\n\nWebexCore.registerInternalPlugin('voicea', VoiceaChannel, {});\n\nexport {default} from './voicea';\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAEA;AAAqC;AAAA;AAErCA,SAAS,CAACC,sBAAsB,CAAC,QAAQ,EAAEC,eAAa,EAAE,CAAC,CAAC,CAAC"}
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';\nexport {EVENT_TRIGGERS, TURN_ON_CAPTION_STATUS} from './constants';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAEA;AAKA;AAAmE;AAAA;AAHnEA,SAAS,CAACC,sBAAsB,CAAC,QAAQ,EAAEC,eAAa,EAAE,CAAC,CAAC,CAAC"}
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.hasVoiceaJoined = true;
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:
@@ -85,6 +86,7 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
85
86
  }, _constants.EVENT_TRIGGERS.NEW_CAPTION, {
86
87
  isFinal: true,
87
88
  transcriptId: voiceaPayload.transcript_id,
89
+ translations: voiceaPayload.translations,
88
90
  transcript: {
89
91
  csis: voiceaPayload.csis,
90
92
  text: voiceaPayload.transcript.text,
@@ -159,8 +161,7 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
159
161
  }, _constants.EVENT_TRIGGERS.VOICEA_ANNOUNCEMENT, voiceaLanguageOptions);
160
162
  });
161
163
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "sendAnnouncement", function () {
162
- // @ts-ignore
163
- if (_this.hasVoiceaJoined || !_this.webex.internal.llm.isConnected()) return;
164
+ _this.announceStatus = _constants.ANNOUNCE_STATUS.JOINING;
164
165
  _this.listenToEvents();
165
166
  // @ts-ignore
166
167
  _this.webex.internal.llm.socket.send({
@@ -190,7 +191,9 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
190
191
  // @ts-ignore
191
192
  url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
192
193
  body: {
193
- languageCode: languageCode
194
+ transcribe: {
195
+ spokenLanguage: languageCode
196
+ }
194
197
  }
195
198
  }).then(function () {
196
199
  _pluginMeetings.TriggerProxy.trigger((0, _assertThisInitialized2.default)(_this), {
@@ -228,70 +231,109 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
228
231
  });
229
232
  _this.seqNum += 1;
230
233
  });
231
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "turnOnCaptions", /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee() {
232
- return _regenerator.default.wrap(function _callee$(_context) {
233
- while (1) switch (_context.prev = _context.next) {
234
- case 0:
235
- if (!(_this.hasVoiceaJoined && _this.areCaptionsEnabled)) {
236
- _context.next = 2;
237
- break;
238
- }
239
- return _context.abrupt("return", undefined);
240
- case 2:
241
- return _context.abrupt("return", _this.request({
242
- method: 'PUT',
243
- // @ts-ignore
244
- url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
245
- body: {
246
- transcribe: {
247
- caption: true
248
- }
249
- }
250
- }).then(function () {
251
- _pluginMeetings.TriggerProxy.trigger((0, _assertThisInitialized2.default)(_this), {
252
- file: 'voicea',
253
- function: 'turnOnCaptions'
254
- }, _constants.EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
255
- _this.areCaptionsEnabled = true;
256
- _this.sendAnnouncement();
257
- }));
258
- case 3:
259
- case "end":
260
- return _context.stop();
261
- }
262
- }, _callee);
263
- })));
264
- (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "toggleTranscribing", /*#__PURE__*/function () {
265
- var _ref2 = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(activate) {
266
- return _regenerator.default.wrap(function _callee2$(_context2) {
267
- while (1) switch (_context2.prev = _context2.next) {
234
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "requestTurnOnCaptions", function (languageCode) {
235
+ _this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.SENDING;
236
+
237
+ // only set the spoken language if it is provided
238
+ var body = {
239
+ transcribe: {
240
+ caption: true
241
+ },
242
+ languageCode: languageCode
243
+ };
244
+
245
+ // @ts-ignore
246
+ // eslint-disable-next-line newline-before-return
247
+ return _this.request({
248
+ method: 'PUT',
249
+ // @ts-ignore
250
+ url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
251
+ body: body
252
+ }).then(function () {
253
+ _pluginMeetings.TriggerProxy.trigger((0, _assertThisInitialized2.default)(_this), {
254
+ file: 'voicea',
255
+ function: 'turnOnCaptions'
256
+ }, _constants.EVENT_TRIGGERS.CAPTIONS_TURNED_ON);
257
+ _this.areCaptionsEnabled = true;
258
+ _this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.ENABLED;
259
+ _this.announce();
260
+ }).catch(function () {
261
+ _this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
262
+ throw new Error('turn on captions fail');
263
+ });
264
+ });
265
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isAnnounceProcessing", function () {
266
+ return [_constants.ANNOUNCE_STATUS.JOINING, _constants.ANNOUNCE_STATUS.JOINED].includes(_this.announceStatus);
267
+ });
268
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "announce", function () {
269
+ if (_this.isAnnounceProcessing()) return;
270
+ // @ts-ignore
271
+ if (!_this.webex.internal.llm.isConnected()) {
272
+ throw new Error('voicea can not announce before llm connected');
273
+ }
274
+ _this.sendAnnouncement();
275
+ });
276
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isCaptionProcessing", function () {
277
+ return [_constants.TURN_ON_CAPTION_STATUS.SENDING, _constants.TURN_ON_CAPTION_STATUS.ENABLED].includes(_this.captionStatus);
278
+ });
279
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "turnOnCaptions", /*#__PURE__*/function () {
280
+ var _ref = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(spokenLanguage) {
281
+ return _regenerator.default.wrap(function _callee$(_context) {
282
+ while (1) switch (_context.prev = _context.next) {
268
283
  case 0:
269
- return _context2.abrupt("return", _this.request({
270
- method: 'PUT',
271
- // @ts-ignore
272
- url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
273
- body: {
274
- transcribe: {
275
- transcribing: activate
276
- }
277
- }
278
- }).then(function () {
279
- if (activate && !_this.areCaptionsEnabled && !_this.hasVoiceaJoined) _this.turnOnCaptions();
280
- }));
281
- case 1:
284
+ if (!_this.isCaptionProcessing()) {
285
+ _context.next = 2;
286
+ break;
287
+ }
288
+ return _context.abrupt("return", undefined);
289
+ case 2:
290
+ if (_this.webex.internal.llm.isConnected()) {
291
+ _context.next = 4;
292
+ break;
293
+ }
294
+ throw new Error('can not turn on captions before llm connected');
295
+ case 4:
296
+ return _context.abrupt("return", _this.requestTurnOnCaptions(spokenLanguage));
297
+ case 5:
282
298
  case "end":
283
- return _context2.stop();
299
+ return _context.stop();
284
300
  }
285
- }, _callee2);
301
+ }, _callee);
286
302
  }));
287
303
  return function (_x) {
288
- return _ref2.apply(this, arguments);
304
+ return _ref.apply(this, arguments);
289
305
  };
290
306
  }());
307
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "toggleTranscribing", function (activate, spokenLanguage) {
308
+ // @ts-ignore
309
+ return _this.request({
310
+ method: 'PUT',
311
+ // @ts-ignore
312
+ url: "".concat(_this.webex.internal.llm.getLocusUrl(), "/controls/"),
313
+ body: {
314
+ transcribe: {
315
+ transcribing: activate
316
+ },
317
+ spokenLanguage: spokenLanguage
318
+ }
319
+ }).then(function () {
320
+ if (activate && !_this.areCaptionsEnabled) {
321
+ return _this.turnOnCaptions(spokenLanguage);
322
+ }
323
+ return undefined;
324
+ });
325
+ });
326
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getCaptionStatus", function () {
327
+ return _this.captionStatus;
328
+ });
329
+ (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getAnnounceStatus", function () {
330
+ return _this.announceStatus;
331
+ });
291
332
  _this.seqNum = 1;
292
- _this.hasVoiceaJoined = false;
293
333
  _this.areCaptionsEnabled = false;
294
334
  _this.vmcDeviceId = undefined;
335
+ _this.announceStatus = _constants.ANNOUNCE_STATUS.IDLE;
336
+ _this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
295
337
  return _this;
296
338
  }
297
339
 
@@ -320,16 +362,20 @@ var VoiceaChannel = /*#__PURE__*/function (_WebexPlugin) {
320
362
  }
321
363
  }
322
364
 
323
- // @ts-ignore
365
+ /**
366
+ * Listen to websocket messages
367
+ * @returns {void}
368
+ */
324
369
  }, {
325
370
  key: "deregisterEvents",
326
371
  value: function deregisterEvents() {
327
- this.hasVoiceaJoined = false;
328
372
  this.areCaptionsEnabled = false;
329
373
  this.vmcDeviceId = undefined;
330
374
  // @ts-ignore
331
375
  this.webex.internal.llm.off('event:relay.event', this.eventProcessor);
332
376
  this.hasSubscribedToEvents = false;
377
+ this.announceStatus = _constants.ANNOUNCE_STATUS.IDLE;
378
+ this.captionStatus = _constants.TURN_ON_CAPTION_STATUS.IDLE;
333
379
  }
334
380
  }]);
335
381
  return VoiceaChannel;
@@ -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 // @ts-ignore\n this.webex.internal.llm.on('event:relay.event', this.eventProcessor);\n this.hasSubscribedToEvents = true;\n }\n }\n\n // @ts-ignore\n public deregisterEvents() {\n this.hasVoiceaJoined = false;\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 }\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 // @ts-ignore\n if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;\n\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 * Turn on Captions\n * @returns {Promise}\n */\n public turnOnCaptions = async (): undefined | Promise<void> => {\n if (this.hasVoiceaJoined && this.areCaptionsEnabled) return undefined;\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 }).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 // @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.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","translations","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","transcribe","spokenLanguage","then","SPOKEN_LANGUAGE_UPDATE","isConnected","to","translationLanguage","TRANSLATION_REQUEST","captionStatus","TURN_ON_CAPTION_STATUS","SENDING","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 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 );\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 transcribe: {\n spokenLanguage: languageCode,\n },\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 * @param {string} [languageCode] - Optional Parameter for spoken language code. Defaults to English\n * @returns {Promise}\n */\n private requestTurnOnCaptions = (languageCode?): undefined | Promise<void> => {\n this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;\n\n // only set the spoken language if it is provided\n const body = {\n transcribe: {caption: true},\n languageCode,\n };\n\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 })\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 * @param {string} [spokenLanguage] - Optional Spoken language code\n * @returns {Promise}\n */\n public turnOnCaptions = async (spokenLanguage?): 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(spokenLanguage);\n };\n\n /**\n * Toggle transcribing for highlights\n * @param {bool} activate if true transcribing is turned on\n * @param {string} spokenLanguage language code for spoken language\n * @returns {Promise}\n */\n public toggleTranscribing = (\n activate: boolean,\n spokenLanguage?: string\n ): 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: {\n transcribing: activate,\n },\n spokenLanguage,\n },\n }).then((): undefined | Promise<void> => {\n if (activate && !this.areCaptionsEnabled) {\n return this.turnOnCaptions(spokenLanguage);\n }\n\n return undefined;\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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"}
@@ -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: () => undefined | Promise<void>;\n}\n\nexport type {\n AnnouncementPayload,\n CaptionLanguageResponse,\n TranscriptionResponse,\n Transcription,\n Highlight,\n IVoiceaChannel,\n};\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 =\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, spokenLanguage: string) => 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.41",
3
+ "version": "3.0.0-beta.411",
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,10 @@
14
14
  "node": ">=16"
15
15
  },
16
16
  "dependencies": {
17
- "@webex/internal-plugin-llm": "3.0.0-beta.41",
18
- "@webex/internal-plugin-mercury": "3.0.0-beta.41",
19
- "@webex/internal-plugin-voicea": "3.0.0-beta.41",
20
- "@webex/plugin-meetings": "3.0.0-beta.41",
21
- "@webex/webex-core": "3.0.0-beta.41",
17
+ "@webex/internal-plugin-llm": "3.0.0-beta.411",
18
+ "@webex/internal-plugin-mercury": "3.0.0-beta.411",
19
+ "@webex/plugin-meetings": "3.0.0-beta.411",
20
+ "@webex/webex-core": "3.0.0-beta.411",
22
21
  "uuid": "^3.3.2"
23
22
  },
24
23
  "browserify": {
@@ -28,9 +27,9 @@
28
27
  ]
29
28
  },
30
29
  "devDependencies": {
31
- "@webex/test-helper-chai": "3.0.0-beta.41",
32
- "@webex/test-helper-mock-web-socket": "3.0.0-beta.41",
33
- "@webex/test-helper-mock-webex": "3.0.0-beta.41",
30
+ "@webex/test-helper-chai": "3.0.0-beta.411",
31
+ "@webex/test-helper-mock-web-socket": "3.0.0-beta.411",
32
+ "@webex/test-helper-mock-webex": "3.0.0-beta.411",
34
33
  "sinon": "^9.2.4"
35
34
  }
36
35
  }
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/index.ts CHANGED
@@ -5,3 +5,4 @@ import VoiceaChannel from './voicea';
5
5
  WebexCore.registerInternalPlugin('voicea', VoiceaChannel, {});
6
6
 
7
7
  export {default} from './voicea';
8
+ export {EVENT_TRIGGERS, TURN_ON_CAPTION_STATUS} from './constants';
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 {EVENT_TRIGGERS, VOICEA_RELAY_TYPES, TRANSCRIPTION_TYPE, VOICEA} from './constants';
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.hasVoiceaJoined = true;
52
+ this.announceStatus = ANNOUNCE_STATUS.JOINED;
44
53
  this.processAnnouncementMessage(e.data.voiceaPayload);
45
54
  break;
46
55
  case VOICEA_RELAY_TYPES.TRANSLATION_RESPONSE:
@@ -66,14 +75,18 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
66
75
  }
67
76
  }
68
77
 
69
- // @ts-ignore
78
+ /**
79
+ * Listen to websocket messages
80
+ * @returns {void}
81
+ */
70
82
  public deregisterEvents() {
71
- this.hasVoiceaJoined = false;
72
83
  this.areCaptionsEnabled = false;
73
84
  this.vmcDeviceId = undefined;
74
85
  // @ts-ignore
75
86
  this.webex.internal.llm.off('event:relay.event', this.eventProcessor);
76
87
  this.hasSubscribedToEvents = false;
88
+ this.announceStatus = ANNOUNCE_STATUS.IDLE;
89
+ this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
77
90
  }
78
91
 
79
92
  /**
@@ -83,9 +96,10 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
83
96
  constructor(...args) {
84
97
  super(...args);
85
98
  this.seqNum = 1;
86
- this.hasVoiceaJoined = false;
87
99
  this.areCaptionsEnabled = false;
88
100
  this.vmcDeviceId = undefined;
101
+ this.announceStatus = ANNOUNCE_STATUS.IDLE;
102
+ this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
89
103
  }
90
104
 
91
105
  /**
@@ -122,6 +136,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
122
136
  {
123
137
  isFinal: true,
124
138
  transcriptId: voiceaPayload.transcript_id,
139
+ translations: voiceaPayload.translations,
125
140
  transcript: {
126
141
  csis: voiceaPayload.csis,
127
142
  text: voiceaPayload.transcript.text,
@@ -243,9 +258,7 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
243
258
  * @returns {void}
244
259
  */
245
260
  private sendAnnouncement = (): void => {
246
- // @ts-ignore
247
- if (this.hasVoiceaJoined || !this.webex.internal.llm.isConnected()) return;
248
-
261
+ this.announceStatus = ANNOUNCE_STATUS.JOINING;
249
262
  this.listenToEvents();
250
263
  // @ts-ignore
251
264
  this.webex.internal.llm.socket.send({
@@ -280,7 +293,9 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
280
293
  // @ts-ignore
281
294
  url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
282
295
  body: {
283
- languageCode,
296
+ transcribe: {
297
+ spokenLanguage: languageCode,
298
+ },
284
299
  },
285
300
  }).then(() => {
286
301
  Trigger.trigger(
@@ -327,52 +342,129 @@ export class VoiceaChannel extends WebexPlugin implements IVoiceaChannel {
327
342
  };
328
343
 
329
344
  /**
330
- * Turn on Captions
345
+ * request turn on Captions
346
+ * @param {string} [languageCode] - Optional Parameter for spoken language code. Defaults to English
331
347
  * @returns {Promise}
332
348
  */
333
- public turnOnCaptions = async (): undefined | Promise<void> => {
334
- if (this.hasVoiceaJoined && this.areCaptionsEnabled) return undefined;
349
+ private requestTurnOnCaptions = (languageCode?): undefined | Promise<void> => {
350
+ this.captionStatus = TURN_ON_CAPTION_STATUS.SENDING;
351
+
352
+ // only set the spoken language if it is provided
353
+ const body = {
354
+ transcribe: {caption: true},
355
+ languageCode,
356
+ };
357
+
335
358
  // @ts-ignore
336
359
  // eslint-disable-next-line newline-before-return
337
360
  return this.request({
338
361
  method: 'PUT',
339
362
  // @ts-ignore
340
363
  url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
341
- body: {
342
- transcribe: {caption: true},
343
- },
344
- }).then(() => {
345
- Trigger.trigger(
346
- this,
347
- {
348
- file: 'voicea',
349
- function: 'turnOnCaptions',
350
- },
351
- EVENT_TRIGGERS.CAPTIONS_TURNED_ON
352
- );
353
- this.areCaptionsEnabled = true;
354
- this.sendAnnouncement();
355
- });
364
+ body,
365
+ })
366
+ .then(() => {
367
+ Trigger.trigger(
368
+ this,
369
+ {
370
+ file: 'voicea',
371
+ function: 'turnOnCaptions',
372
+ },
373
+ EVENT_TRIGGERS.CAPTIONS_TURNED_ON
374
+ );
375
+ this.areCaptionsEnabled = true;
376
+ this.captionStatus = TURN_ON_CAPTION_STATUS.ENABLED;
377
+ this.announce();
378
+ })
379
+ .catch(() => {
380
+ this.captionStatus = TURN_ON_CAPTION_STATUS.IDLE;
381
+ throw new Error('turn on captions fail');
382
+ });
383
+ };
384
+
385
+ /**
386
+ * is announce processing
387
+ * @returns {boolean}
388
+ */
389
+ private isAnnounceProcessing = () =>
390
+ [ANNOUNCE_STATUS.JOINING, ANNOUNCE_STATUS.JOINED].includes(this.announceStatus);
391
+
392
+ /**
393
+ * announce to voicea data chanel
394
+ * @returns {void}
395
+ */
396
+ public announce = () => {
397
+ if (this.isAnnounceProcessing()) return;
398
+ // @ts-ignore
399
+ if (!this.webex.internal.llm.isConnected()) {
400
+ throw new Error('voicea can not announce before llm connected');
401
+ }
402
+ this.sendAnnouncement();
403
+ };
404
+
405
+ /**
406
+ * is turn on caption processing
407
+ * @returns {boolean}
408
+ */
409
+ private isCaptionProcessing = () =>
410
+ [TURN_ON_CAPTION_STATUS.SENDING, TURN_ON_CAPTION_STATUS.ENABLED].includes(this.captionStatus);
411
+
412
+ /**
413
+ * Turn on Captions
414
+ * @param {string} [spokenLanguage] - Optional Spoken language code
415
+ * @returns {Promise}
416
+ */
417
+ public turnOnCaptions = async (spokenLanguage?): undefined | Promise<void> => {
418
+ if (this.isCaptionProcessing()) return undefined;
419
+ // @ts-ignore
420
+ if (!this.webex.internal.llm.isConnected()) {
421
+ throw new Error('can not turn on captions before llm connected');
422
+ }
423
+
424
+ return this.requestTurnOnCaptions(spokenLanguage);
356
425
  };
357
426
 
358
427
  /**
359
428
  * Toggle transcribing for highlights
360
429
  * @param {bool} activate if true transcribing is turned on
430
+ * @param {string} spokenLanguage language code for spoken language
361
431
  * @returns {Promise}
362
432
  */
363
- public toggleTranscribing = async (activate: boolean): undefined | Promise<void> => {
433
+ public toggleTranscribing = (
434
+ activate: boolean,
435
+ spokenLanguage?: string
436
+ ): undefined | Promise<void> => {
364
437
  // @ts-ignore
365
438
  return this.request({
366
439
  method: 'PUT',
367
440
  // @ts-ignore
368
441
  url: `${this.webex.internal.llm.getLocusUrl()}/controls/`,
369
442
  body: {
370
- transcribe: {transcribing: activate},
443
+ transcribe: {
444
+ transcribing: activate,
445
+ },
446
+ spokenLanguage,
371
447
  },
372
- }).then(() => {
373
- if (activate && !this.areCaptionsEnabled && !this.hasVoiceaJoined) this.turnOnCaptions();
448
+ }).then((): undefined | Promise<void> => {
449
+ if (activate && !this.areCaptionsEnabled) {
450
+ return this.turnOnCaptions(spokenLanguage);
451
+ }
452
+
453
+ return undefined;
374
454
  });
375
455
  };
456
+
457
+ /**
458
+ * get caption status
459
+ * @returns {string}
460
+ */
461
+ public getCaptionStatus = () => this.captionStatus;
462
+
463
+ /**
464
+ * get announce status
465
+ * @returns {string}
466
+ */
467
+ public getAnnounceStatus = () => this.announceStatus;
376
468
  }
377
469
 
378
470
  export default VoiceaChannel;
@@ -78,8 +78,8 @@ interface IVoiceaChannel {
78
78
  setSpokenLanguage: (languageCode: string) => Promise<void>;
79
79
  requestLanguage: (languageCode: string) => void;
80
80
  turnOnCaptions: () => undefined | Promise<void>;
81
- toggleTranscribing: (activate: boolean) => undefined | Promise<void>;
82
- deregisterEvents: () => undefined | Promise<void>;
81
+ toggleTranscribing: (activate: boolean, spokenLanguage: string) => undefined | Promise<void>;
82
+ deregisterEvents: () => void;
83
83
  }
84
84
 
85
85
  export type {
@@ -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', () => {
@@ -192,28 +202,38 @@ describe('plugin-voicea', () => {
192
202
  sinon.match({
193
203
  method: 'PUT',
194
204
  url: `${locusUrl}/controls/`,
195
- body: {languageCode},
205
+ body: {
206
+ transcribe: {
207
+ spokenLanguage: languageCode
208
+ }
209
+ },
196
210
  })
197
211
  );
198
212
  });
199
213
  });
200
214
 
201
- describe('#turnOnCaptions', () => {
215
+ describe('#requestTurnOnCaptions', () => {
202
216
  beforeEach(async () => {
203
217
  const mockWebSocket = new MockWebSocket();
204
218
 
205
219
  voiceaService.webex.internal.llm.socket = mockWebSocket;
220
+ voiceaService.captionStatus = 'idle';
206
221
  });
207
222
 
223
+ afterEach( () => {
224
+ voiceaService.captionStatus = 'idle';
225
+ })
226
+
208
227
  it('turns on captions', async () => {
209
- const announcementSpy = sinon.spy(voiceaService, 'sendAnnouncement');
228
+ const announcementSpy = sinon.spy(voiceaService, 'announce');
210
229
 
211
230
  const triggerSpy = sinon.spy();
212
231
 
213
232
  voiceaService.on(EVENT_TRIGGERS.CAPTIONS_TURNED_ON, triggerSpy);
214
233
  voiceaService.listenToEvents();
215
234
 
216
- await voiceaService.turnOnCaptions();
235
+ await voiceaService.requestTurnOnCaptions();
236
+ assert.equal(voiceaService.captionStatus, 'enabled');
217
237
  sinon.assert.calledWith(
218
238
  voiceaService.request,
219
239
  sinon.match({
@@ -228,18 +248,119 @@ describe('plugin-voicea', () => {
228
248
  assert.calledOnce(announcementSpy);
229
249
  });
230
250
 
231
- it("doesn't call API on captions", async () => {
232
- await voiceaService.turnOnCaptions();
251
+ it("should handle request fail", async () => {
252
+ voiceaService.captionStatus = 'sending';
253
+ voiceaService.request = sinon.stub().rejects();
254
+
255
+ try {
256
+ await voiceaService.requestTurnOnCaptions();
257
+ } catch (error) {
258
+ expect(error.message).to.include('turn on captions fail');
259
+ return;
260
+ }
261
+ assert.equal(voiceaService.captionStatus, 'idle');
262
+ });
263
+ });
233
264
 
234
- // eslint-disable-next-line no-underscore-dangle
235
- voiceaService.webex.internal.llm._emit('event:relay.event', {
236
- headers: {from: 'ws'},
237
- data: {relayType: 'voicea.annc', voiceaPayload: {}},
265
+ describe("#isAnnounceProcessing", () => {
266
+ afterEach(() => {
267
+ voiceaService.announceStatus = 'idle';
268
+ });
269
+
270
+ ['joining', 'joined'].forEach((status) => {
271
+ it(`should return true when status is ${status}`, () => {
272
+ voiceaService.announceStatus = status;
273
+ assert.equal(voiceaService.isAnnounceProcessing(), true);
238
274
  });
275
+ });
276
+
277
+ it('should return false when status is not processing status', () => {
278
+ voiceaService.announceStatus = 'idle';
279
+ assert.equal(voiceaService.isAnnounceProcessing(), false);
280
+ });
281
+ });
282
+
283
+ describe("#announce", () => {
284
+ let isAnnounceProcessing, sendAnnouncement;
285
+ beforeEach(() => {
286
+ voiceaService.webex.internal.llm.isConnected.returns(true);
287
+ sendAnnouncement = sinon.stub(voiceaService, 'sendAnnouncement');
288
+ isAnnounceProcessing = sinon.stub(voiceaService, 'isAnnounceProcessing').returns(false)
289
+ });
239
290
 
240
- const response = await voiceaService.turnOnCaptions();
291
+ afterEach(() => {
292
+ voiceaService.webex.internal.llm.isConnected.returns(true);
293
+ isAnnounceProcessing.restore();
294
+ sendAnnouncement.restore();
295
+ });
241
296
 
242
- assert.equal(response, undefined);
297
+ it('announce to llm data channel', ()=> {
298
+ voiceaService.announce();
299
+ assert.calledOnce(sendAnnouncement);
300
+ });
301
+
302
+ it('announce to llm data channel before llm connected', ()=> {
303
+ voiceaService.webex.internal.llm.isConnected.returns(false);
304
+ assert.throws(() => voiceaService.announce(), "voicea can not announce before llm connected");
305
+ assert.notCalled(sendAnnouncement);
306
+ });
307
+
308
+ it('should not announce duplicate', () => {
309
+ isAnnounceProcessing.returns(true);
310
+ voiceaService.announce();
311
+ assert.notCalled(sendAnnouncement);
312
+ })
313
+ });
314
+
315
+ describe("#isCaptionProcessing", () => {
316
+ afterEach(() => {
317
+ voiceaService.captionStatus = 'idle';
318
+ });
319
+
320
+ ['sending', 'enabled'].forEach((status) => {
321
+ it(`should return true when status is ${status}`, () => {
322
+ voiceaService.captionStatus = status;
323
+ assert.equal(voiceaService.isCaptionProcessing(), true);
324
+ });
325
+ });
326
+
327
+ it('should return false when status is not processing status', () => {
328
+ voiceaService.captionStatus = 'idle';
329
+ assert.equal(voiceaService.isCaptionProcessing(), false);
330
+ });
331
+ });
332
+
333
+ describe('#turnOnCaptions', () => {
334
+ let requestTurnOnCaptions, isCaptionProcessing;
335
+ beforeEach(() => {
336
+ requestTurnOnCaptions = sinon.stub(voiceaService, 'requestTurnOnCaptions');
337
+ isCaptionProcessing = sinon.stub(voiceaService, 'isCaptionProcessing').returns(false);
338
+ voiceaService.webex.internal.llm.isConnected.returns(true);
339
+ });
340
+
341
+ afterEach(() => {
342
+ requestTurnOnCaptions.restore();
343
+ isCaptionProcessing.restore();
344
+ voiceaService.webex.internal.llm.isConnected.returns(true);
345
+ });
346
+
347
+ it('call request turn on captions', () => {
348
+ isCaptionProcessing.returns(false);
349
+ voiceaService.turnOnCaptions();
350
+ assert.calledOnce(requestTurnOnCaptions);
351
+ });
352
+
353
+ it("turns on captions before llm connected", () => {
354
+ isCaptionProcessing.returns(false);
355
+ voiceaService.webex.internal.llm.isConnected.returns(true);
356
+ // assert.throws(() => voiceaService.turnOnCaptions(), "can not turn on captions before llm connected");
357
+ assert.notCalled(requestTurnOnCaptions);
358
+ });
359
+
360
+ it('should not turn on duplicate when processing', () => {
361
+ isCaptionProcessing.returns(true);
362
+ voiceaService.turnOnCaptions();
363
+ assert.notCalled(voiceaService.requestTurnOnCaptions);
243
364
  });
244
365
  });
245
366
 
@@ -430,6 +551,9 @@ describe('plugin-voicea', () => {
430
551
  transcript_id: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
431
552
  ts: 1611653204.3147924,
432
553
  type: 'transcript_final_result',
554
+ translations: {
555
+ en: "Hello?",
556
+ },
433
557
  transcript: {
434
558
  alignments: [
435
559
  {
@@ -479,6 +603,9 @@ describe('plugin-voicea', () => {
479
603
  assert.calledOnceWithExactly(triggerSpy, {
480
604
  isFinal: true,
481
605
  transcriptId: '3ec73890-bffb-f28b-e77f-99dc13caea7e',
606
+ translations: {
607
+ en: "Hello?"
608
+ },
482
609
  transcript: {
483
610
  csis: [3556942592],
484
611
  text: 'Hello?',
@@ -613,5 +740,19 @@ describe('plugin-voicea', () => {
613
740
  });
614
741
  });
615
742
  });
743
+
744
+ describe("#getCaptionStatus", () => {
745
+ it('works correctly', () => {
746
+ voiceaService.captionStatus = "enabled"
747
+ assert.equal(voiceaService.getCaptionStatus(), "enabled");
748
+ });
749
+ });
750
+
751
+ describe("#getAnnounceStatus", () => {
752
+ it('works correctly', () => {
753
+ voiceaService.announceStatus = "joined"
754
+ assert.equal(voiceaService.getAnnounceStatus(), "joined");
755
+ });
756
+ });
616
757
  });
617
758
  });